feat: blind接口解析问题
This commit is contained in:
parent
df32ea71bb
commit
36b95abc37
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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)")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user