feat: blind接口解析问题

This commit is contained in:
jinyaqiu 2025-09-03 14:12:50 +08:00
parent df32ea71bb
commit 36b95abc37
3 changed files with 124 additions and 23 deletions

View File

@ -74,7 +74,7 @@ struct BlindBoxView: View {
case all case all
} }
// //
struct BlindList: Codable, Identifiable { struct BlindList: Codable, Identifiable, Equatable, Hashable {
let id: Int64 let id: Int64
let boxCode: String let boxCode: String
let userId: Int64 let userId: Int64
@ -104,6 +104,40 @@ struct BlindBoxView: View {
case coverFileId = "cover_file_id" case coverFileId = "cover_file_id"
case description case description
} }
// Implement Equatable
static func == (lhs: BlindBoxView.BlindList, rhs: BlindBoxView.BlindList) -> Bool {
return lhs.id == rhs.id &&
lhs.boxCode == rhs.boxCode &&
lhs.userId == rhs.userId &&
lhs.name == rhs.name &&
lhs.boxType == rhs.boxType &&
lhs.features == rhs.features &&
lhs.resultFileId == rhs.resultFileId &&
lhs.status == rhs.status &&
lhs.workflowInstanceId == rhs.workflowInstanceId &&
lhs.videoGenerateTime == rhs.videoGenerateTime &&
lhs.createTime == rhs.createTime &&
lhs.coverFileId == rhs.coverFileId &&
lhs.description == rhs.description
}
// Implement Hashable
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(boxCode)
hasher.combine(userId)
hasher.combine(name)
hasher.combine(boxType)
hasher.combine(features)
hasher.combine(resultFileId)
hasher.combine(status)
hasher.combine(workflowInstanceId)
hasher.combine(videoGenerateTime)
hasher.combine(createTime)
hasher.combine(coverFileId)
hasher.combine(description)
}
} }
// //
struct BlindCount: Codable { struct BlindCount: Codable {
@ -114,22 +148,35 @@ struct BlindBoxView: View {
} }
} }
// MARK: - BlindBox Response Model // MARK: - API Response Wrapper
struct APIResponse<T: Codable>: Codable {
let code: Int
let data: T
let message: String?
enum CodingKeys: String, CodingKey {
case code
case data
case message
}
}
struct BlindBoxData: Codable { // MARK: - BlindBox Response Model
struct BlindBoxData: Codable, Equatable {
let id: Int64 let id: Int64
let boxCode: String let boxCode: String
let userId: Int64 let userId: Int64
let name: String let name: String
let boxType: String let boxType: String
let features: String? let features: String?
let url: String? let resultFileId: Int64?
let status: String let status: String
let workflowInstanceId: String? let workflowInstanceId: String
//
let videoGenerateTime: String? let videoGenerateTime: String?
let createTime: String let createTime: String
let description: String? let coverFileId: Int64?
let url: String?
let description: String
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case id case id
@ -138,29 +185,59 @@ struct BlindBoxView: View {
case name case name
case boxType = "box_type" case boxType = "box_type"
case features case features
case url case resultFileId = "result_file_id"
case status case status
case workflowInstanceId = "workflow_instance_id" case workflowInstanceId = "workflow_instance_id"
case videoGenerateTime = "video_generate_time" case videoGenerateTime = "video_generate_time"
case createTime = "create_time" case createTime = "create_time"
case coverFileId = "cover_file_id"
case url
case description case description
} }
init(id: Int64, boxCode: String, userId: Int64, name: String, boxType: String, features: String?, url: String?, status: String, workflowInstanceId: String?, videoGenerateTime: String?, createTime: String, description: String?) { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Required fields with default values
id = try container.decode(Int64.self, forKey: .id)
boxCode = try container.decodeIfPresent(String.self, forKey: .boxCode) ?? ""
userId = try container.decode(Int64.self, forKey: .userId)
name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
boxType = try container.decode(String.self, forKey: .boxType)
status = try container.decode(String.self, forKey: .status)
workflowInstanceId = try container.decode(String.self, forKey: .workflowInstanceId)
createTime = try container.decode(String.self, forKey: .createTime)
// Optional fields
features = try container.decodeIfPresent(String.self, forKey: .features)
resultFileId = try container.decodeIfPresent(Int64.self, forKey: .resultFileId)
videoGenerateTime = try container.decodeIfPresent(String.self, forKey: .videoGenerateTime)
coverFileId = try container.decodeIfPresent(Int64.self, forKey: .coverFileId)
url = try container.decodeIfPresent(String.self, forKey: .url)
description = try container.decodeIfPresent(String.self, forKey: .description) ?? ""
}
// Initializer for creating instances manually
init(id: Int64, boxCode: String, userId: Int64, name: String, boxType: String, features: String?,
resultFileId: Int64?, status: String, workflowInstanceId: String, videoGenerateTime: String?,
createTime: String, coverFileId: Int64?, url: String?, description: String) {
self.id = id self.id = id
self.boxCode = boxCode self.boxCode = boxCode
self.userId = userId self.userId = userId
self.name = name self.name = name
self.boxType = boxType self.boxType = boxType
self.features = features self.features = features
self.url = url self.resultFileId = resultFileId
self.status = status self.status = status
self.workflowInstanceId = workflowInstanceId self.workflowInstanceId = workflowInstanceId
self.videoGenerateTime = videoGenerateTime self.videoGenerateTime = videoGenerateTime
self.createTime = createTime self.createTime = createTime
self.coverFileId = coverFileId
self.url = url
self.description = description self.description = description
} }
// Initializer for creating from BlindList
init(from listItem: BlindList) { init(from listItem: BlindList) {
self.init( self.init(
id: listItem.id, id: listItem.id,
@ -169,17 +246,28 @@ struct BlindBoxView: View {
name: listItem.name, name: listItem.name,
boxType: listItem.boxType, boxType: listItem.boxType,
features: listItem.features, features: listItem.features,
url: nil, resultFileId: listItem.resultFileId,
status: listItem.status, status: listItem.status,
workflowInstanceId: listItem.workflowInstanceId, workflowInstanceId: listItem.workflowInstanceId ?? "",
videoGenerateTime: listItem.videoGenerateTime, videoGenerateTime: listItem.videoGenerateTime,
createTime: listItem.createTime, createTime: listItem.createTime,
coverFileId: listItem.coverFileId,
url: nil,
description: listItem.description description: listItem.description
) )
} }
// Equatable conformance
static func == (lhs: BlindBoxData, rhs: BlindBoxData) -> Bool {
return lhs.id == rhs.id &&
lhs.workflowInstanceId == rhs.workflowInstanceId &&
lhs.status == rhs.status
}
} }
let mediaType: BlindBoxMediaType let mediaType: BlindBoxMediaType
private var ids: [String]?
@State private var blindBoxItems: [BlindList]?
@State private var showModal = false // @State private var showModal = false //
@State private var showSettings = false // @State private var showSettings = false //
@State private var isMember = false // @State private var isMember = false //
@ -217,8 +305,9 @@ struct BlindBoxView: View {
// - // -
@Query private var login: [Login] @Query private var login: [Login]
init(mediaType: BlindBoxMediaType) { init(mediaType: BlindBoxMediaType, ids: [String]? = nil) {
self.mediaType = mediaType self.mediaType = mediaType
self.ids = ids
} }
// //
@ -343,9 +432,19 @@ struct BlindBoxView: View {
return return
} }
//
var parameters: [String: Any] = ["box_type": currentBoxType=="Video" ? "Second" : "First"]
//
if let ids = ids, !ids.isEmpty {
let fileIds = ids.compactMap { Int64($0) } // Convert string to Int64
print("material_ids: \(fileIds)")
parameters["material_ids"] = fileIds
}
NetworkService.shared.postWithToken( NetworkService.shared.postWithToken(
path: "/blind_box/generate/mock", path: "/blind_box/generate",
parameters: ["box_type": currentBoxType] parameters: parameters
) { (result: Result<APIResponse<BlindBoxData>, NetworkError>) in ) { (result: Result<APIResponse<BlindBoxData>, NetworkError>) in
DispatchQueue.main.async { DispatchQueue.main.async {
switch result { switch result {
@ -534,7 +633,7 @@ struct BlindBoxView: View {
default: default:
// //
withAnimation { withAnimation {
self.animationPhase = .ready self.animationPhase = .loading
} }
break break
} }

View File

@ -7,7 +7,7 @@ enum AppRoute: Hashable {
case feedbackView case feedbackView
case feedbackDetail(type: FeedbackView.FeedbackType) case feedbackDetail(type: FeedbackView.FeedbackType)
case mediaUpload case mediaUpload
case blindBox(mediaType: BlindBoxView.BlindBoxMediaType) case blindBox(mediaType: BlindBoxView.BlindBoxMediaType, ids: [String]? = nil)
case blindOutcome(media: MediaType, time: String? = nil, description: String? = nil) case blindOutcome(media: MediaType, time: String? = nil, description: String? = nil)
case memories case memories
case subscribe case subscribe
@ -31,8 +31,8 @@ enum AppRoute: Hashable {
FeedbackDetailView(feedbackType: type) FeedbackDetailView(feedbackType: type)
case .mediaUpload: case .mediaUpload:
MediaUploadView() MediaUploadView()
case .blindBox(let mediaType): case .blindBox(let mediaType, let ids):
BlindBoxView(mediaType: mediaType) BlindBoxView(mediaType: mediaType, ids: ids)
case .blindOutcome(let media, let time, let description): case .blindOutcome(let media, let time, let description):
BlindOutcomeView(media: media, time: time, description: description) BlindOutcomeView(media: media, time: time, description: description)
case .memories: case .memories:

View File

@ -315,7 +315,6 @@ struct MediaUploadView: View {
/// ///
private func handleContinue() { private func handleContinue() {
// //
Router.shared.navigate(to: .blindBox(mediaType: .video))
let uploadResults = uploadManager.uploadResults let uploadResults = uploadManager.uploadResults
guard !uploadResults.isEmpty else { guard !uploadResults.isEmpty else {
print("⚠️ 没有可用的文件ID") print("⚠️ 没有可用的文件ID")
@ -329,7 +328,10 @@ struct MediaUploadView: View {
"preview_file_id": result.thumbnailId ?? result.fileId "preview_file_id": result.thumbnailId ?? result.fileId
] ]
} }
let filesID = uploadResults.map { (_, result) -> String in
return result.fileId
}
// POST/material // POST/material
NetworkService.shared.postWithToken( NetworkService.shared.postWithToken(
path: "/material", path: "/material",
@ -338,9 +340,9 @@ struct MediaUploadView: View {
switch result { switch result {
case .success: case .success:
print("✅ 素材提交成功") print("✅ 素材提交成功")
// //
DispatchQueue.main.async { DispatchQueue.main.async {
Router.shared.navigate(to: .blindBox(mediaType: .video)) Router.shared.navigate(to: .blindBox(mediaType: .video, ids: filesID))
} }
case .failure(let error): case .failure(let error):
print("❌ 素材提交失败: \(error.localizedDescription)") print("❌ 素材提交失败: \(error.localizedDescription)")