feat: 文件上传成功
This commit is contained in:
parent
a63d363001
commit
a1f26f13bf
@ -5,6 +5,7 @@ import PhotosUI
|
|||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
// MARK: - Photo Picker
|
// MARK: - Photo Picker
|
||||||
=======
|
=======
|
||||||
/// 上传管理器,处理图片上传
|
/// 上传管理器,处理图片上传
|
||||||
@ -205,6 +206,8 @@ public struct UploadResults {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
// MARK: - Photo Picker
|
// MARK: - Photo Picker
|
||||||
|
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
@ -213,6 +216,7 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
=======
|
=======
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
|
||||||
/// 绑定的已选图片数组,用于存储用户选择的图片
|
/// 绑定的已选图片数组,用于存储用户选择的图片
|
||||||
@ -260,14 +264,29 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
=======
|
=======
|
||||||
var onImageUploaded: ((Result<UploadResults, Error>) -> Void)?
|
var onImageUploaded: ((Result<UploadResults, Error>) -> Void)?
|
||||||
var onUploadProgress: ((UploadProgress) -> Void)?
|
var onUploadProgress: ((UploadProgress) -> Void)?
|
||||||
|
=======
|
||||||
|
|
||||||
|
@Binding var selectedImages: [UIImage]
|
||||||
|
let selectionLimit: Int
|
||||||
|
let filter: PHPickerFilter
|
||||||
|
var onImageUploaded: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
|
||||||
|
var onUploadProgress: ((ImageUploadService.UploadProgress) -> Void)?
|
||||||
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
// MARK: - Initialization
|
// MARK: - Initialization
|
||||||
|
|
||||||
init(selectedImages: Binding<[UIImage]>,
|
init(selectedImages: Binding<[UIImage]>,
|
||||||
selectionLimit: Int = 1,
|
selectionLimit: Int = 1,
|
||||||
filter: PHPickerFilter = .images,
|
filter: PHPickerFilter = .images,
|
||||||
|
<<<<<<< HEAD
|
||||||
onImageUploaded: ((Result<UploadResults, Error>) -> Void)? = nil,
|
onImageUploaded: ((Result<UploadResults, Error>) -> Void)? = nil,
|
||||||
onUploadProgress: ((UploadProgress) -> Void)? = nil) {
|
onUploadProgress: ((UploadProgress) -> Void)? = nil) {
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
|
=======
|
||||||
|
onImageUploaded: ((Result<ImageUploadService.UploadResults, Error>) -> Void)? = nil,
|
||||||
|
onUploadProgress: ((ImageUploadService.UploadProgress) -> Void)? = nil) {
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
self._selectedImages = selectedImages
|
self._selectedImages = selectedImages
|
||||||
self.selectionLimit = selectionLimit
|
self.selectionLimit = selectionLimit
|
||||||
self.filter = filter
|
self.filter = filter
|
||||||
@ -280,6 +299,7 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UIViewControllerRepresentable
|
// MARK: - UIViewControllerRepresentable
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
|
||||||
// MARK: - UIViewControllerRepresentable 协议方法
|
// MARK: - UIViewControllerRepresentable 协议方法
|
||||||
@ -292,6 +312,9 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
/// 创建并返回配置好的PHPickerViewController
|
/// 创建并返回配置好的PHPickerViewController
|
||||||
=======
|
=======
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
|
=======
|
||||||
|
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
func makeUIViewController(context: Context) -> PHPickerViewController {
|
func makeUIViewController(context: Context) -> PHPickerViewController {
|
||||||
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
|
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
|
||||||
configuration.filter = filter
|
configuration.filter = filter
|
||||||
@ -311,6 +334,7 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
|
|
||||||
// MARK: - Coordinator
|
// MARK: - Coordinator
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
|
||||||
// MARK: - 协调器类
|
// MARK: - 协调器类
|
||||||
@ -329,15 +353,27 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
=======
|
=======
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
private let uploader = ImageUploaderGetID()
|
private let uploader = ImageUploaderGetID()
|
||||||
|
=======
|
||||||
|
|
||||||
|
class Coordinator: NSObject, PHPickerViewControllerDelegate {
|
||||||
|
let parent: PhotoPicker
|
||||||
|
private let uploadService = ImageUploadService.shared
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
init(_ parent: PhotoPicker) {
|
init(_ parent: PhotoPicker) {
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
}
|
}
|
||||||
|
|
||||||
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
|
||||||
|
guard !results.isEmpty else {
|
||||||
|
parent.presentationMode.wrappedValue.dismiss()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
parent.selectedImages.removeAll()
|
parent.selectedImages.removeAll()
|
||||||
let group = DispatchGroup()
|
let group = DispatchGroup()
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
var loadedImages: [Int: UIImage] = [:]
|
var loadedImages: [Int: UIImage] = [:]
|
||||||
var uploadResults: [Int: ImageUploadService.UploadResults] = [:]
|
var uploadResults: [Int: ImageUploadService.UploadResults] = [:]
|
||||||
@ -355,11 +391,17 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
var uploadResults: [Int: (original: ImageUploaderGetID.UploadResult?,
|
var uploadResults: [Int: (original: ImageUploaderGetID.UploadResult?,
|
||||||
compressed: ImageUploaderGetID.UploadResult?)] = [:]
|
compressed: ImageUploaderGetID.UploadResult?)] = [:]
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
|
=======
|
||||||
|
var loadedImages: [Int: UIImage] = [:]
|
||||||
|
var uploadResults: [Int: ImageUploadService.UploadResults] = [:]
|
||||||
|
var lastError: Error?
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
for (index, result) in results.enumerated() {
|
for (index, result) in results.enumerated() {
|
||||||
group.enter()
|
group.enter()
|
||||||
|
|
||||||
if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
|
if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
|
||||||
|
<<<<<<< HEAD
|
||||||
result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, error) in
|
result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, error) in
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
if let image = image as? UIImage {
|
if let image = image as? UIImage {
|
||||||
@ -370,12 +412,24 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
loadedImages[index] = image
|
loadedImages[index] = image
|
||||||
=======
|
=======
|
||||||
guard let self = self, let image = image as? UIImage else {
|
guard let self = self, let image = image as? UIImage else {
|
||||||
|
=======
|
||||||
|
result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
|
||||||
|
if let error = error {
|
||||||
|
lastError = error
|
||||||
|
group.leave()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let image = image as? UIImage else {
|
||||||
|
lastError = NSError(domain: "com.wake.upload", code: -2, userInfo: [NSLocalizedDescriptionKey: "Failed to load image"])
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
group.leave()
|
group.leave()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedImages[index] = image
|
loadedImages[index] = image
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
guard let compressedImage = image.jpegData(compressionQuality: 0.5).flatMap(UIImage.init(data:)) else {
|
guard let compressedImage = image.jpegData(compressionQuality: 0.5).flatMap(UIImage.init(data:)) else {
|
||||||
group.leave()
|
group.leave()
|
||||||
return
|
return
|
||||||
@ -426,77 +480,48 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
}
|
}
|
||||||
=======
|
=======
|
||||||
self.uploader.uploadImage(
|
self.uploader.uploadImage(
|
||||||
|
=======
|
||||||
|
// Upload the image
|
||||||
|
self.uploadService.uploadOriginalAndCompressedImage(
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
image,
|
image,
|
||||||
progress: { [weak self] progress in
|
compressionQuality: 0.5,
|
||||||
let progressInfo = UploadProgress(
|
progress: { progress in
|
||||||
current: Int(progress * 100),
|
|
||||||
total: 100,
|
|
||||||
progress: progress,
|
|
||||||
isOriginal: true
|
|
||||||
)
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self?.parent.onUploadProgress?(progressInfo)
|
self.parent.onUploadProgress?(progress)
|
||||||
}
|
}
|
||||||
print("📤 原图上传进度: \(Int(progress * 100))%")
|
|
||||||
},
|
},
|
||||||
|
<<<<<<< HEAD
|
||||||
completion: { [weak self] originalResult in
|
completion: { [weak self] originalResult in
|
||||||
guard let self = self else {
|
guard let self = self else {
|
||||||
group.leave()
|
group.leave()
|
||||||
return
|
return
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
completion: { result in
|
||||||
|
defer { group.leave() }
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
switch originalResult {
|
switch result {
|
||||||
case .success(let originalUploadResult):
|
case .success(let results):
|
||||||
self.uploader.uploadImage(
|
uploadResults[index] = results
|
||||||
compressedImage,
|
|
||||||
progress: { [weak self] progress in
|
// Upload file info to backend
|
||||||
let progressInfo = UploadProgress(
|
MaterialService.shared.uploadMaterialInfo(
|
||||||
current: Int(progress * 100),
|
fileId: results.original.fileId,
|
||||||
total: 100,
|
previewFileId: results.compressed.fileId
|
||||||
progress: progress,
|
) { success, errorMessage in
|
||||||
isOriginal: false
|
if success {
|
||||||
)
|
print("✅ 文件信息上传成功")
|
||||||
DispatchQueue.main.async {
|
} else if let errorMessage = errorMessage {
|
||||||
self?.parent.onUploadProgress?(progressInfo)
|
print("❌ 文件信息上传失败: \(errorMessage)")
|
||||||
}
|
|
||||||
print("📊 压缩图上传进度: \(Int(progress * 100))%")
|
|
||||||
},
|
|
||||||
completion: { 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) 字节")
|
|
||||||
|
|
||||||
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)")
|
|
||||||
uploadResults[index] = (originalUploadResult, nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
print("❌ 原图上传失败: \(error.localizedDescription)")
|
lastError = error
|
||||||
group.leave()
|
print("❌ 图片上传失败: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -535,28 +560,33 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
group.notify(queue: .main) { [weak self] in
|
group.notify(queue: .main) { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
let sortedImages = loadedImages.sorted { $0.key < $1.key }.map { $0.value }
|
if let error = lastError {
|
||||||
self.parent.selectedImages.append(contentsOf: sortedImages)
|
self.parent.onImageUploaded?(.failure(error))
|
||||||
|
|
||||||
if let firstResult = uploadResults.first?.value,
|
|
||||||
let original = firstResult.original,
|
|
||||||
let compressed = firstResult.compressed {
|
|
||||||
let results = UploadResults(original: original, compressed: compressed)
|
|
||||||
self.parent.onImageUploaded?(.success(results))
|
|
||||||
} else {
|
} else {
|
||||||
self.parent.onImageUploaded?(.failure(NSError(
|
let sortedImages = loadedImages.sorted { $0.key < $1.key }.map { $0.value }
|
||||||
domain: "com.wake.upload",
|
self.parent.selectedImages.append(contentsOf: sortedImages)
|
||||||
code: -1,
|
|
||||||
userInfo: [NSLocalizedDescriptionKey: "上传过程中出现错误"]
|
if let firstResult = uploadResults.first?.value {
|
||||||
)))
|
self.parent.onImageUploaded?(.success(firstResult))
|
||||||
|
} else {
|
||||||
|
self.parent.onImageUploaded?(.failure(NSError(
|
||||||
|
domain: "com.wake.upload",
|
||||||
|
code: -1,
|
||||||
|
userInfo: [NSLocalizedDescriptionKey: "上传过程中出现错误"]
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
// 5. 关闭图片选择器
|
// 5. 关闭图片选择器
|
||||||
>>>>>>> 5611df8 (feat: 素材上传成)
|
>>>>>>> 5611df8 (feat: 素材上传成)
|
||||||
=======
|
=======
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
picker.dismiss(animated: true)
|
picker.dismiss(animated: true)
|
||||||
|
=======
|
||||||
|
self.parent.presentationMode.wrappedValue.dismiss()
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -579,6 +609,7 @@ struct PhotoPicker: UIViewControllerRepresentable {
|
|||||||
struct AvatarUploader: View {
|
struct AvatarUploader: View {
|
||||||
@Binding var selectedImage: UIImage?
|
@Binding var selectedImage: UIImage?
|
||||||
let size: CGFloat
|
let size: CGFloat
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
var onUploadComplete: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
|
var onUploadComplete: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
|
||||||
|
|
||||||
@ -586,6 +617,9 @@ struct AvatarUploader: View {
|
|||||||
=======
|
=======
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
var onUploadComplete: ((Result<UploadResults, Error>) -> Void)?
|
var onUploadComplete: ((Result<UploadResults, Error>) -> Void)?
|
||||||
|
=======
|
||||||
|
var onUploadComplete: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
@State private var isImagePickerPresented = false
|
@State private var isImagePickerPresented = false
|
||||||
|
|
||||||
@ -662,7 +696,7 @@ struct AvatarUploader: View {
|
|||||||
onUploadComplete?(result)
|
onUploadComplete?(result)
|
||||||
},
|
},
|
||||||
onUploadProgress: { progress in
|
onUploadProgress: { progress in
|
||||||
print("上传进度:\(progress.current)/\(progress.total),进度:\(progress.progress * 100)%")
|
print("上传进度:\(progress.current)/\(progress.total),进度:\(Int(progress.progress * 100))%")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,15 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
// MARK: - 类型定义
|
// MARK: - 类型定义
|
||||||
|
|
||||||
/// 上传结果
|
/// 上传结果
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
public struct UploadResult: Codable {
|
public struct UploadResult: Codable {
|
||||||
=======
|
=======
|
||||||
public struct UploadResult {
|
public struct UploadResult {
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
public struct UploadResult: Codable {
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
public let fileUrl: String
|
public let fileUrl: String
|
||||||
public let fileName: String
|
public let fileName: String
|
||||||
public let fileSize: Int
|
public let fileSize: Int
|
||||||
@ -33,10 +37,14 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
case invalidResponse
|
case invalidResponse
|
||||||
case uploadFailed(Error?)
|
case uploadFailed(Error?)
|
||||||
case invalidFileId
|
case invalidFileId
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
case invalidResponseData
|
case invalidResponseData
|
||||||
=======
|
=======
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
case invalidResponseData
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
public var errorDescription: String? {
|
public var errorDescription: String? {
|
||||||
switch self {
|
switch self {
|
||||||
@ -52,11 +60,16 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
return "上传失败: \(error?.localizedDescription ?? "未知错误")"
|
return "上传失败: \(error?.localizedDescription ?? "未知错误")"
|
||||||
case .invalidFileId:
|
case .invalidFileId:
|
||||||
return "无效的文件ID"
|
return "无效的文件ID"
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
case .invalidResponseData:
|
case .invalidResponseData:
|
||||||
return "无效的响应数据"
|
return "无效的响应数据"
|
||||||
=======
|
=======
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
case .invalidResponseData:
|
||||||
|
return "无效的响应数据"
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,6 +250,7 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
|
|
||||||
/// 确认上传
|
/// 确认上传
|
||||||
private func confirmUpload(fileId: String, fileName: String, fileSize: Int, completion: @escaping (Result<UploadResult, Error>) -> Void) {
|
private func confirmUpload(fileId: String, fileName: String, fileSize: Int, completion: @escaping (Result<UploadResult, Error>) -> Void) {
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
let endpoint = "\(apiConfig.baseURL)/file/confirm-upload"
|
let endpoint = "\(apiConfig.baseURL)/file/confirm-upload"
|
||||||
guard let url = URL(string: endpoint) else {
|
guard let url = URL(string: endpoint) else {
|
||||||
@ -244,6 +258,10 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
let urlString = "\(apiConfig.baseURL)/file/confirm-upload"
|
let urlString = "\(apiConfig.baseURL)/file/confirm-upload"
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
let endpoint = "\(apiConfig.baseURL)/file/confirm-upload"
|
||||||
|
guard let url = URL(string: endpoint) else {
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
completion(.failure(UploadError.invalidURL))
|
completion(.failure(UploadError.invalidURL))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -253,11 +271,15 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
request.allHTTPHeaderFields = apiConfig.authHeaders
|
request.allHTTPHeaderFields = apiConfig.authHeaders
|
||||||
|
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
let body: [String: Any] = [
|
let body: [String: Any] = [
|
||||||
"file_id": fileId,
|
"file_id": fileId,
|
||||||
"file_name": fileName,
|
"file_name": fileName,
|
||||||
"file_size": fileSize
|
"file_size": fileSize
|
||||||
]
|
]
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
do {
|
do {
|
||||||
request.httpBody = try JSONSerialization.data(withJSONObject: body)
|
request.httpBody = try JSONSerialization.data(withJSONObject: body)
|
||||||
@ -266,26 +288,40 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
print("❌ 序列化确认上传参数失败: \(error.localizedDescription)")
|
print("❌ 序列化确认上传参数失败: \(error.localizedDescription)")
|
||||||
=======
|
=======
|
||||||
let requestBody: [String: Any] = ["file_id": fileId]
|
let requestBody: [String: Any] = ["file_id": fileId]
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
request.httpBody = try JSONSerialization.data(withJSONObject: requestBody)
|
request.httpBody = try JSONSerialization.data(withJSONObject: body)
|
||||||
|
print("📤 确认上传请求,fileId: \(fileId), 文件名: \(fileName)")
|
||||||
} catch {
|
} catch {
|
||||||
|
<<<<<<< HEAD
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
print("❌ 序列化确认上传参数失败: \(error.localizedDescription)")
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
completion(.failure(error))
|
completion(.failure(error))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = session.dataTask(with: request) { data, response, error in
|
let task = session.dataTask(with: request) { data, response, error in
|
||||||
if let error = error {
|
if let error = error {
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
print("❌ 确认上传请求失败: \(error.localizedDescription)")
|
print("❌ 确认上传请求失败: \(error.localizedDescription)")
|
||||||
=======
|
=======
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
print("❌ 确认上传请求失败: \(error.localizedDescription)")
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
completion(.failure(UploadError.uploadFailed(error)))
|
completion(.failure(UploadError.uploadFailed(error)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
guard let httpResponse = response as? HTTPURLResponse else {
|
guard let httpResponse = response as? HTTPURLResponse else {
|
||||||
print("❌ 无效的服务器响应")
|
print("❌ 无效的服务器响应")
|
||||||
completion(.failure(UploadError.invalidResponse))
|
completion(.failure(UploadError.invalidResponse))
|
||||||
@ -297,11 +333,14 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
let errorMessage = "确认上传失败,状态码: \(statusCode)"
|
let errorMessage = "确认上传失败,状态码: \(statusCode)"
|
||||||
print("❌ \(errorMessage)")
|
print("❌ \(errorMessage)")
|
||||||
completion(.failure(UploadError.serverError(errorMessage)))
|
completion(.failure(UploadError.serverError(errorMessage)))
|
||||||
|
<<<<<<< HEAD
|
||||||
=======
|
=======
|
||||||
guard let httpResponse = response as? HTTPURLResponse,
|
guard let httpResponse = response as? HTTPURLResponse,
|
||||||
(200...299).contains(httpResponse.statusCode) else {
|
(200...299).contains(httpResponse.statusCode) else {
|
||||||
completion(.failure(UploadError.serverError("确认上传失败,状态码: \((response as? HTTPURLResponse)?.statusCode ?? -1)")))
|
completion(.failure(UploadError.serverError("确认上传失败,状态码: \((response as? HTTPURLResponse)?.statusCode ?? -1)")))
|
||||||
>>>>>>> a207b78 (feat: 确认上传)
|
>>>>>>> a207b78 (feat: 确认上传)
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,6 +391,9 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
guard let httpResponse = response as? HTTPURLResponse else {
|
guard let httpResponse = response as? HTTPURLResponse else {
|
||||||
completion(.failure(UploadError.invalidResponse))
|
completion(.failure(UploadError.invalidResponse))
|
||||||
return
|
return
|
||||||
@ -359,11 +401,14 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
|
|
||||||
guard httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 else {
|
guard httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 else {
|
||||||
let statusCode = httpResponse.statusCode
|
let statusCode = httpResponse.statusCode
|
||||||
|
<<<<<<< HEAD
|
||||||
=======
|
=======
|
||||||
guard let httpResponse = response as? HTTPURLResponse,
|
guard let httpResponse = response as? HTTPURLResponse,
|
||||||
(200...299).contains(httpResponse.statusCode) else {
|
(200...299).contains(httpResponse.statusCode) else {
|
||||||
let statusCode = (response as? HTTPURLResponse)?.statusCode ?? -1
|
let statusCode = (response as? HTTPURLResponse)?.statusCode ?? -1
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
|
=======
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
completion(.failure(UploadError.serverError("上传失败,状态码: \(statusCode)")))
|
completion(.failure(UploadError.serverError("上传失败,状态码: \(statusCode)")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -384,11 +429,15 @@ public class ImageUploaderGetID: ObservableObject {
|
|||||||
task?.progress.cancel()
|
task?.progress.cancel()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
<<<<<<< HEAD
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
// iOS 11 以下版本使用通知
|
// iOS 11 以下版本使用通知
|
||||||
=======
|
=======
|
||||||
// Fallback for earlier iOS versions
|
// Fallback for earlier iOS versions
|
||||||
>>>>>>> 8e641fd (feat: 上传进度)
|
>>>>>>> 8e641fd (feat: 上传进度)
|
||||||
|
=======
|
||||||
|
// iOS 11 以下版本使用通知
|
||||||
|
>>>>>>> 5edee64 (feat: 文件上传成功)
|
||||||
var lastProgress: Double = 0
|
var lastProgress: Double = 0
|
||||||
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
|
let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
|
||||||
let bytesSent = task.countOfBytesSent
|
let bytesSent = task.countOfBytesSent
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user