feat: 调取接口

This commit is contained in:
jinyaqiu 2025-08-29 18:09:01 +08:00
parent f96edf97c5
commit ee1b1321ff
2 changed files with 201 additions and 46 deletions

View File

@ -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<APIResponse<MemberProfile>, 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<APIResponse<BlindCount>, 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<APIResponse<[BlindList]>, 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<APIResponse<MemberProfile>, 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)

View File

@ -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<T: Codable>: 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<APIResponse<UserProfile>, NetworkError>) in
DispatchQueue.main.async {
isLoading = false
switch result {
case .success(let response):
self.userProfile = response.data