feat: 触发生成第一个盲盒

This commit is contained in:
Junhui Chen 2025-09-07 01:06:52 +08:00
parent 8fb6d5c6b9
commit e9cdb82b70
5 changed files with 212 additions and 12 deletions

View File

@ -0,0 +1,111 @@
import Foundation
// MARK: - Generate Blind Box Request Model
// struct GenerateBlindBoxRequest: Codable {
// let boxType: String
// let materialIds: [String]
// enum CodingKeys: String, CodingKey {
// case boxType = "box_type"
// case materialIds = "material_ids"
// }
// }
// MARK: - Generate Blind Box Response Model
struct GenerateBlindBoxResponse: Codable {
let code: Int
let data: BlindBoxDataWrapper?
struct BlindBoxDataWrapper: Codable {
let id: String
let boxCode: String
let userId: String
let name: String
let boxType: String
let features: String?
let resultFile: FileInfo?
let status: String
let workflowInstanceId: String?
let videoGenerateTime: String?
let createTime: String
let coverFile: FileInfo?
let description: String
// Int64
var idValue: Int64 { Int64(id) ?? 0 }
var userIdValue: Int64 { Int64(userId) ?? 0 }
struct FileInfo: Codable {
let id: String
let fileName: String?
let url: String?
let metadata: [String: String]?
enum CodingKeys: String, CodingKey {
case id
case fileName = "file_name"
case url
case metadata
}
}
enum CodingKeys: String, CodingKey {
case id
case boxCode = "box_code"
case userId = "user_id"
case name
case boxType = "box_type"
case features
case resultFile = "result_file"
case status
case workflowInstanceId = "workflow_instance_id"
case videoGenerateTime = "video_generate_time"
case createTime = "create_time"
case coverFile = "cover_file"
case description
}
}
}
// MARK: - Blind Box API Client
class BlindBoxApi {
static let shared = BlindBoxApi()
private init() {}
///
/// - Parameters:
/// - boxType: ( "First")
/// - materialIds: ID
/// - completion:
func generateBlindBox(
boxType: String,
materialIds: [String],
completion: @escaping (Result<GenerateBlindBoxResponse.BlindBoxDataWrapper?, Error>) -> Void
) {
// Codable
let parameters: [String: Any] = [
"box_type": boxType,
"material_ids": materialIds
]
NetworkService.shared.postWithToken(
path: "/blind_box/generate",
parameters: parameters,
completion: { (result: Result<GenerateBlindBoxResponse, NetworkError>) in
DispatchQueue.main.async {
switch result {
case .success(let response):
if response.code == 0 {
completion(.success(response.data))
} else {
completion(.failure(NetworkError.serverError("服务器返回错误码: \(response.code)")))
}
case .failure(let error):
completion(.failure(error))
}
}
}
)
}
}

View File

@ -0,0 +1,66 @@
import Foundation
// MARK: -
struct MaterialRequest: Codable {
let fileId: String
let previewFileId: String
enum CodingKeys: String, CodingKey {
case fileId = "file_id"
case previewFileId = "preview_file_id"
}
}
struct AddMaterialResponse: Codable {
let code: Int
let data: [String]?
}
// MARK: -
class MaterialUpload {
static let shared = MaterialUpload()
private init() {}
///
/// - Parameters:
/// - fileId: ID
/// - previewFileId: ID
/// - completion: ID
func addMaterial(
fileId: String,
previewFileId: String,
completion: @escaping (Result<[String]?, Error>) -> Void
) {
//
let materials: [[String: String]] = [[
"file_id": fileId,
"preview_file_id": previewFileId
]]
// JSON
print("🔍 准备发送的参数: \(materials)")
// 使NetworkService
NetworkService.shared.post(
path: "/material",
parameters: materials,
completion: { (result: Result<AddMaterialResponse, NetworkError>) in
DispatchQueue.main.async {
switch result {
case .success(let response):
if response.code == 0 {
completion(.success(response.data))
} else {
completion(.failure(NetworkError.serverError("服务器返回错误码: \(response.code)")))
}
case .failure(let error):
print("❌ 素材上传失败: \(error.localizedDescription)")
completion(.failure(error))
}
}
}
)
}
}

View File

@ -116,7 +116,7 @@ struct UserInfo: View {
// Content VStack
VStack(spacing: 20) {
// Title
Text(showUsername ? "Add Your Avatar" : "What's Your Name?")
Text(showUsername ? "What's Your Name?" : "Add Your Avatar")
.font(Typography.font(for: .body, family: .quicksandBold))
.frame(maxWidth: .infinity, alignment: .center)
@ -181,11 +181,32 @@ struct UserInfo: View {
self.userName = userData.username
}
//
MaterialUpload.shared.addMaterial(
fileId: uploadedFileId ?? "",
previewFileId: uploadedFileId ?? ""
) { result in
switch result {
case .success(let data):
print("素材添加成功返回ID: \(data ?? [])")
//
BlindBoxApi.shared.generateBlindBox(
boxType: "First",
materialIds: data ?? []
) { result in
switch result {
case .success(let blindBoxData):
print("✅ 盲盒生成成功: \(blindBoxData?.id ?? "0")")
//
Router.shared.navigate(to: .blindBox(mediaType: .image))
case .failure(let error):
print("❌ 盲盒生成失败: \(error.localizedDescription)")
}
}
case .failure(let error):
print("素材添加失败: \(error.localizedDescription)")
}
}
case .failure(let error):
print("❌ 用户信息更新失败: \(error.localizedDescription)")
self.errorMessage = "更新失败: \(error.localizedDescription)"
@ -199,7 +220,8 @@ struct UserInfo: View {
}
}
}) {
Text(showUsername ? "Open" : "Continue")
// Text(showUsername ? "Open" : "Continue")
Text("Continue")
.font(Typography.font(for: .body))
.fontWeight(.bold)
.frame(maxWidth: .infinity)

View File

@ -46,10 +46,11 @@ struct WakeApp: App {
if authState.isAuthenticated {
//
NavigationStack(path: $router.path) {
BlindBoxView(mediaType: .all)
.navigationDestination(for: AppRoute.self) { route in
route.view
}
// BlindBoxView(mediaType: .all)
// .navigationDestination(for: AppRoute.self) { route in
// route.view
// }
UserInfo()
}
} else {
//