diff --git a/wake/ContentView.swift b/wake/ContentView.swift index 7508dbe..665f0ba 100644 --- a/wake/ContentView.swift +++ b/wake/ContentView.swift @@ -74,11 +74,138 @@ struct BlindBoxView: View { case image case all } + // 盲盒列表 + struct BlindList: Codable, Identifiable { + let id: Int64 + let boxCode: String + let userId: Int64 + let name: String + let boxType: String + let features: String? + let resultFileId: Int64? + let status: String + let workflowInstanceId: String? + let videoGenerateTime: String? + let createTime: String + let coverFileId: Int64? + let description: String + + enum CodingKeys: String, CodingKey { + case id + case boxCode = "box_code" + case userId = "user_id" + case name + case boxType = "box_type" + case features + case resultFileId = "result_file_id" + case status + case workflowInstanceId = "workflow_instance_id" + case videoGenerateTime = "video_generate_time" + case createTime = "create_time" + case coverFileId = "cover_file_id" + case description + } + } + // 会员信息 + struct MemberProfile: Codable { + let materialCounter: MaterialCounter + let userInfo: UserInfo + let storiesCount: Int + let conversationsCount: Int + let remainPoints: Int + let totalPoints: Int + let usedBytes: Int + let totalBytes: Int + let titleRankings: [String] + let medalInfos: [MedalInfo] + let membershipLevel: String + let membershipEndAt: String + + enum CodingKeys: String, CodingKey { + case materialCounter = "material_counter" + case userInfo = "user_info" + case storiesCount = "stories_count" + case conversationsCount = "conversations_count" + case remainPoints = "remain_points" + case totalPoints = "total_points" + case usedBytes = "used_bytes" + case totalBytes = "total_bytes" + case titleRankings = "title_rankings" + case medalInfos = "medal_infos" + case membershipLevel = "membership_level" + case membershipEndAt = "membership_end_at" + } + } + // 盲盒数量 + struct BlindCount: Codable { + let availableQuantity: Int + + enum CodingKeys: String, CodingKey { + case availableQuantity = "available_quantity" + } + } + + struct MaterialCounter: Codable { + let userId: Int64 + let totalCount: MediaCount + let categoryCount: [String: MediaCount] + + enum CodingKeys: String, CodingKey { + case userId = "user_id" + case totalCount = "total_count" + case categoryCount = "category_count" + } + } + + struct MediaCount: Codable { + let videoCount: Int + let photoCount: Int + let liveCount: Int + let videoLength: Double + let coverUrl: String? + + enum CodingKeys: String, CodingKey { + case videoCount = "video_count" + case photoCount = "photo_count" + case liveCount = "live_count" + case videoLength = "video_length" + case coverUrl = "cover_url" + } + } + + struct UserInfo: Codable { + let userId: String + let accessToken: String + let avatarFileUrl: String? + let nickname: String + let account: String + let email: String + let refreshToken: String? + + enum CodingKeys: String, CodingKey { + case userId = "user_id" + case accessToken = "access_token" + case avatarFileUrl = "avatar_file_url" + case nickname + case account + case email + case refreshToken = "refresh_token" + } + } + + struct MedalInfo: Codable, Identifiable { + let id: Int + let url: String + } + let mediaType: BlindBoxMediaType @State private var showModal = false // 控制用户资料弹窗显示 @State private var showSettings = false // 控制设置页面显示 @State private var showLogin = false + @State private var memberProfile: MemberProfile? = nil + @State private var blindCount: BlindCount? = nil + @State private var blindList: [BlindList] = [] // Changed to array @State private var showLottieAnimation = true @State private var showScalingOverlay = false @State private var animationPhase: BlindBoxAnimationPhase = .loading @@ -98,27 +225,85 @@ struct BlindBoxView: View { } private func loadMedia() { + print("loadMedia called with mediaType: \(mediaType)") + switch mediaType { case .video: loadVideo() + print("Loading video...") case .image: loadImage() + print("Loading image...") case .all: - loadData() + print("Loading all content...") + // 会员信息 + NetworkService.shared.get( + path: "/membership/personal-center-info", + parameters: nil + ) { (result: Result, NetworkError>) in + DispatchQueue.main.async { + switch result { + case .success(let response): + self.memberProfile = response.data + print("✅ 成功获取会员信息:", response.data) + print("✅ 用户ID:", response.data.userInfo.userId) + print("✅ 用户昵称:", response.data.userInfo.nickname) + print("✅ 用户邮箱:", response.data.userInfo.email) + case .failure(let error): + print("❌ 获取会员信息失败:", error) + } + } + } + // 盲盒数量 + NetworkService.shared.get( + path: "/blind_box/available/quantity", + parameters: nil + ) { (result: Result, NetworkError>) in + DispatchQueue.main.async { + switch result { + case .success(let response): + self.blindCount = response.data + print("✅ 成功获取盲盒数量:", response.data) + case .failure(let error): + print("❌ 获取数量失败:", error) + } + } + } + // 盲盒列表 + NetworkService.shared.get( + path: "/blind_boxs/query", + parameters: nil + ) { (result: Result, NetworkError>) in + DispatchQueue.main.async { + switch result { + case .success(let response): + self.blindList = response.data ?? [] + print("✅ 成功获取 \(self.blindList.count) 个盲盒") + case .failure(let error): + self.blindList = [] + print("❌ 获取盲盒列表失败:", error.localizedDescription) + } + } + } } } private func loadData() { - guard let url = URL(string: MediaURLs.imageURL) else { return } - URLSession.shared.dataTask(with: url) { data, _, _ in - if let data = data, let image = UIImage(data: data) { - DispatchQueue.main.async { - self.displayImage = image - self.aspectRatio = image.size.width / image.size.height - self.isPortrait = image.size.height > image.size.width + // 会员信息 + NetworkService.shared.get( + path: "/membership/personal-center-info", + parameters: nil + ) { (result: Result, NetworkError>) in + DispatchQueue.main.async { + switch result { + case .success(let response): + self.memberProfile = response.data + print("✅ Successfully fetched user info:", response.data) + case .failure(let error): + print("❌ Failed to fetch user info:", error) } } - }.resume() + } } private func loadImage() { @@ -183,6 +368,11 @@ struct BlindBoxView: View { var body: some View { ZStack { Color.themeTextWhiteSecondary.ignoresSafeArea() + .onAppear { + print("🎯 BlindBoxView appeared with mediaType: \(mediaType)") + print("🎯 Current thread: \(Thread.current)") + loadMedia() + } if showScalingOverlay { ZStack { @@ -299,7 +489,7 @@ struct BlindBoxView: View { // LoginView() // } NavigationLink(destination: SubscribeView()) { - Text("3290") + Text("\(memberProfile?.remainPoints ?? 0)") .font(Typography.font(for: .subtitle)) .fontWeight(.bold) .padding(.horizontal, 12) @@ -396,7 +586,7 @@ struct BlindBoxView: View { SVGImage(svgName: "BlindCount") .frame(width: 100, height: 60) - Text("2 Boxes") + Text("\(blindCount?.availableQuantity ?? 0)Boxes") .font(Typography.font(for: .body, family: .quicksandBold)) .foregroundColor(.white) .offset(x: 6, y: -18) diff --git a/wake/View/Components/UserProfileModal.swift b/wake/View/Components/UserProfileModal.swift index 936d30a..6724c5a 100644 --- a/wake/View/Components/UserProfileModal.swift +++ b/wake/View/Components/UserProfileModal.swift @@ -16,23 +16,6 @@ struct UserProfile: Codable { case email } } - -struct MemberProfile: Codable { - let userId: String - let nickname: String - let avatarUrl: String? - let account: String - let email: String - - enum CodingKeys: String, CodingKey { - case userId = "user_id" - case nickname - case avatarUrl = "avatar_file_url" - case account - case email - } -} - // API Response wrapper struct APIResponse: Codable { let code: Int @@ -301,24 +284,6 @@ struct UserProfileModal: View { DispatchQueue.main.async { isLoading = false - switch result { - case .success(let response): - self.userProfile = response.data - print("✅ Successfully fetched user info:", response.data) - case .failure(let error): - self.errorMessage = error.localizedDescription - print("❌ Failed to fetch user info:", error) - } - } - } - // 会员信息 - NetworkService.shared.get( - path: "/membership/personal-center-info", - parameters: nil - ) { (result: Result, NetworkError>) in - DispatchQueue.main.async { - isLoading = false - switch result { case .success(let response): self.userProfile = response.data