diff --git a/yana.xcodeproj/project.pbxproj b/yana.xcodeproj/project.pbxproj index 956b577..ed82228 100644 --- a/yana.xcodeproj/project.pbxproj +++ b/yana.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ 4C4C8FBE2DE5AF9200384527 /* yanaAPITests */ = { isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + ); path = yanaAPITests; sourceTree = ""; }; @@ -256,14 +258,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-resources.sh\"\n"; @@ -277,14 +275,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-yana/Pods-yana-frameworks.sh\"\n"; diff --git a/yana/APIs/DynamicsModels.swift b/yana/APIs/DynamicsModels.swift index d221cf8..b675fdb 100644 --- a/yana/APIs/DynamicsModels.swift +++ b/yana/APIs/DynamicsModels.swift @@ -241,12 +241,56 @@ struct PublishFeedData: Codable, Equatable { // MARK: - 我的动态 API 请求 +/// 我的动态信息结构 - 专门用于 /dynamic/getMyDynamic 接口 +struct MyMomentInfo: Codable, Equatable, Sendable { + let content: String + let uid: Int + let publishTime: Int64 + let type: Int + + // 转换为 MomentsInfo 的辅助方法 + func toMomentsInfo() -> MomentsInfo { + return MomentsInfo( + dynamicId: 0, // 我的动态接口没有返回 dynamicId + uid: uid, + nick: "", // 需要从用户信息中获取 + avatar: "", // 需要从用户信息中获取 + type: type, + content: content, + likeCount: 0, // 我的动态接口没有返回点赞数 + isLike: false, // 我的动态接口没有返回点赞状态 + commentCount: 0, // 我的动态接口没有返回评论数 + publishTime: Int(publishTime / 1000), // 转换为秒 + worldId: 0, // 我的动态接口没有返回 worldId + status: 1, // 默认状态 + playCount: nil, + dynamicResList: nil, + gender: nil, + squareTop: nil, + topicTop: nil, + newUser: nil, + defUser: nil, + scene: nil, + userVipInfoVO: nil, + headwearPic: nil, + headwearEffect: nil, + headwearType: nil, + headwearName: nil, + headwearId: nil, + experLevelPic: nil, + charmLevelPic: nil, + isCustomWord: nil, + labelList: nil + ) + } +} + /// 我的动态响应结构 struct MyMomentsResponse: Codable, Equatable, Sendable { let code: Int let message: String - let data: [MomentsInfo]? - let timestamp: Int? + let data: [MyMomentInfo]? + let timestamp: Int64? } struct GetMyDynamicRequest: APIRequestProtocol { diff --git a/yana/APIs/LoginModels.swift b/yana/APIs/LoginModels.swift index 2f03f0f..478762e 100644 --- a/yana/APIs/LoginModels.swift +++ b/yana/APIs/LoginModels.swift @@ -77,10 +77,29 @@ struct IDLoginAPIRequest: APIRequestProtocol { let endpoint = APIEndpoint.login.path // 使用枚举定义的登录端点 let method: HTTPMethod = .POST let includeBaseParameters = true - let queryParameters: [String: String]? var bodyParameters: [String: Any]? { nil } let timeout: TimeInterval = 30.0 + // MARK: - Private Properties + private let phone: String + private let password: String + private let clientSecret: String + private let version: String + private let clientId: String + private let grantType: String + + // MARK: - Computed Properties + var queryParameters: [String: String]? { + return [ + "phone": phone, + "password": password, + "client_secret": clientSecret, + "version": version, + "client_id": clientId, + "grant_type": grantType + ] + } + /// 初始化ID登录请求 /// - Parameters: /// - phone: DES加密后的用户ID/手机号 @@ -90,14 +109,12 @@ struct IDLoginAPIRequest: APIRequestProtocol { /// - clientId: 客户端ID,固定为"erban-client" /// - grantType: 授权类型,固定为"password" init(phone: String, password: String, clientSecret: String = "uyzjdhds", version: String = "1", clientId: String = "erban-client", grantType: String = "password") { - self.queryParameters = [ - "phone": phone, - "password": password, - "client_secret": clientSecret, - "version": version, - "client_id": clientId, - "grant_type": grantType - ]; + self.phone = phone + self.password = password + self.clientSecret = clientSecret + self.version = version + self.clientId = clientId + self.grantType = grantType } } @@ -527,10 +544,29 @@ struct EmailLoginRequest: APIRequestProtocol { let endpoint = APIEndpoint.login.path let method: HTTPMethod = .POST let includeBaseParameters = true - let queryParameters: [String: String]? var bodyParameters: [String: Any]? { nil } let timeout: TimeInterval = 30.0 + // MARK: - Private Properties + private let email: String + private let code: String + private let clientSecret: String + private let version: String + private let clientId: String + private let grantType: String + + // MARK: - Computed Properties + var queryParameters: [String: String]? { + return [ + "email": email, + "code": code, + "client_secret": clientSecret, + "version": version, + "client_id": clientId, + "grant_type": grantType + ] + } + /// 初始化邮箱验证码登录请求 /// - Parameters: /// - email: DES加密后的邮箱地址 @@ -540,14 +576,12 @@ struct EmailLoginRequest: APIRequestProtocol { /// - clientId: 客户端ID,固定为"erban-client" /// - grantType: 授权类型,固定为"email" init(email: String, code: String, clientSecret: String = "uyzjdhds", version: String = "1", clientId: String = "erban-client", grantType: String = "email") { - self.queryParameters = [ - "email": email, - "code": code, - "client_secret": clientSecret, - "version": version, - "client_id": clientId, - "grant_type": grantType - ] + self.email = email + self.code = code + self.clientSecret = clientSecret + self.version = version + self.clientId = clientId + self.grantType = grantType } } @@ -603,18 +637,25 @@ struct GetUserInfoRequest: APIRequestProtocol { let endpoint = APIEndpoint.getUserInfo.path let method: HTTPMethod = .GET let includeBaseParameters = true - let queryParameters: [String: String]? var bodyParameters: [String: Any]? { nil } let timeout: TimeInterval = 30.0 let shouldShowLoading: Bool = false // 不显示loading,避免影响用户体验 let shouldShowError: Bool = false // 不显示错误,静默处理 + // MARK: - Private Properties + private let uid: String + + // MARK: - Computed Properties + var queryParameters: [String: String]? { + return [ + "uid": uid + ] + } + /// 初始化获取用户信息请求 /// - Parameter uid: 要查询的用户ID init(uid: String) { - self.queryParameters = [ - "uid": uid - ] + self.uid = uid } } diff --git a/yana/Configs/AppConfig.swift b/yana/Configs/AppConfig.swift index 7390a74..5166e0a 100644 --- a/yana/Configs/AppConfig.swift +++ b/yana/Configs/AppConfig.swift @@ -5,17 +5,16 @@ enum AppEnvironment { struct AppConfig { static let current: AppEnvironment = { - #if DEBUG - return .development - #else +// #if DEBUG +// return .development +// #else return .production - #endif +// #endif }() static var baseURL: String { switch current { case .development: -// return "http://192.168.10.211:8080" return "http://beta.api.molistar.xyz" case .production: return "https://api.epartylive.com" diff --git a/yana/Features/FeedListFeature.swift b/yana/Features/FeedListFeature.swift index 3fa6feb..c21137a 100644 --- a/yana/Features/FeedListFeature.swift +++ b/yana/Features/FeedListFeature.swift @@ -112,24 +112,36 @@ struct FeedListFeature { case .fetchFeeds: state.isLoading = true state.error = nil + debugInfoSync("🔄 FeedListFeature: 开始获取动态") // 发起 API 请求 return .run { [apiService] send in await send(.fetchFeedsResponse(TaskResult { let request = LatestDynamicsRequest(dynamicId: "", pageSize: 20, types: [.text, .picture]) + debugInfoSync("📡 FeedListFeature: 发送请求: \(request.endpoint)") + debugInfoSync(" 参数: dynamicId=\(request.dynamicId), pageSize=\(request.pageSize)") return try await apiService.request(request) })) } case let .fetchFeedsResponse(.success(response)): state.isLoading = false + debugInfoSync("✅ FeedListFeature: API 请求成功") + debugInfoSync(" 响应码: \(response.code)") + debugInfoSync(" 消息: \(response.message)") + debugInfoSync(" 数据数量: \(response.data?.dynamicList.count ?? 0)") if let list = response.data?.dynamicList { state.moments = list state.error = nil state.currentPage = 1 state.hasMore = (list.count >= 20) + debugInfoSync("✅ FeedListFeature: 数据加载成功") + debugInfoSync(" 动态数量: \(list.count)") + debugInfoSync(" 是否有更多: \(state.hasMore)") } else { state.moments = [] state.error = response.message state.hasMore = false + debugErrorSync("❌ FeedListFeature: 数据为空") + debugErrorSync(" 错误消息: \(response.message)") } return .none case let .fetchFeedsResponse(.failure(error)): @@ -137,6 +149,8 @@ struct FeedListFeature { state.moments = [] state.error = error.localizedDescription state.hasMore = false + debugErrorSync("❌ FeedListFeature: API 请求失败") + debugErrorSync(" 错误: \(error.localizedDescription)") return .none case .editFeedButtonTapped: state.isEditFeedPresented = true diff --git a/yana/Features/MainFeature.swift b/yana/Features/MainFeature.swift index 673ceff..feeeecd 100644 --- a/yana/Features/MainFeature.swift +++ b/yana/Features/MainFeature.swift @@ -23,7 +23,17 @@ struct MainFeature { init(accountModel: AccountModel? = nil) { self.accountModel = accountModel let uid = accountModel?.uid.flatMap { Int($0) } ?? 0 - self.me = MeFeature.State(displayUID: uid > 0 ? uid : nil) + debugInfoSync("🏗️ MainFeature 初始化") + debugInfoSync(" accountModel.uid: \(accountModel?.uid ?? "nil")") + debugInfoSync(" 转换后的uid: \(uid)") + var meState = MeFeature.State(displayUID: uid > 0 ? uid : nil) + if uid > 0 { + meState.uid = uid // 确保uid与displayUID一致 + } + self.me = meState + debugInfoSync(" meState.uid: \(meState.uid)") + debugInfoSync(" meState.displayUID: \(meState.displayUID ?? -1)") + debugInfoSync(" meState.effectiveUID: \(meState.effectiveUID)") } } @@ -68,6 +78,7 @@ struct MainFeature { if tab == .other, let uidStr = state.accountModel?.uid, let uid = Int(uidStr), uid > 0 { if state.me.displayUID != uid { state.me.displayUID = uid + state.me.uid = uid // 同步更新uid state.me.isFirstLoad = true } return .send(.me(.onAppear)) @@ -90,6 +101,7 @@ struct MainFeature { if state.selectedTab == .other, let uidStr = accountModel?.uid, let uid = Int(uidStr), uid > 0 { if state.me.displayUID != uid { state.me.displayUID = uid + state.me.uid = uid // 同步更新uid state.me.isFirstLoad = true } return .send(.me(.onAppear)) diff --git a/yana/Features/MeDynamicFeature.swift b/yana/Features/MeDynamicFeature.swift index 1c46ea8..c958edb 100644 --- a/yana/Features/MeDynamicFeature.swift +++ b/yana/Features/MeDynamicFeature.swift @@ -61,7 +61,9 @@ struct MeDynamicFeature: Reducer { state.isLoadingMore = false switch result { case let .success(resp): - let newDynamics = resp.data ?? [] + let myMoments = resp.data ?? [] + // 将 MyMomentInfo 转换为 MomentsInfo + let newDynamics = myMoments.map { $0.toMomentsInfo() } if state.page == 1 { state.dynamics = newDynamics } else { @@ -80,11 +82,21 @@ struct MeDynamicFeature: Reducer { private func fetchDynamics(uid: Int, page: Int, pageSize: Int) -> Effect { let apiService = self.apiService return .run { send in + debugInfoSync("🔄 MeDynamicFeature: 开始获取动态") + debugInfoSync(" UID: \(uid)") + debugInfoSync(" 页码: \(page)") + debugInfoSync(" 页大小: \(pageSize)") + do { let req = GetMyDynamicRequest(fromUid: uid, uid: uid, page: page, pageSize: pageSize) let resp = try await apiService.request(req) + debugInfoSync("✅ MeDynamicFeature: API 请求成功") + debugInfoSync(" 响应码: \(resp.code)") + debugInfoSync(" 消息: \(resp.message)") + debugInfoSync(" 数据数量: \(resp.data?.count ?? 0)") await send(.fetchResponse(.success(resp))) } catch { + debugErrorSync("❌ MeDynamicFeature: API 请求失败: \(error.localizedDescription)") await send(.fetchResponse(.failure(error as? APIError ?? .unknown(error.localizedDescription)))) } } diff --git a/yana/Features/MeFeature.swift b/yana/Features/MeFeature.swift index 1e6f2f0..ce4603e 100644 --- a/yana/Features/MeFeature.swift +++ b/yana/Features/MeFeature.swift @@ -27,6 +27,10 @@ struct MeFeature { init(displayUID: Int? = nil) { self.displayUID = displayUID + // 如果displayUID不为nil,说明要显示指定用户,将其设置为uid + if let displayUID = displayUID { + self.uid = displayUID + } } // 获取实际要显示的用户ID @@ -57,13 +61,20 @@ struct MeFeature { switch action { case .onAppear: guard state.isFirstLoad else { return .none } + debugInfoSync("📱 MeFeature onAppear") + debugInfoSync(" isFirstLoad: \(state.isFirstLoad)") + debugInfoSync(" effectiveUID: \(state.effectiveUID)") state.isFirstLoad = false return .send(.refresh) case .refresh: guard state.effectiveUID > 0 else { return .none } + debugInfoSync("🔄 MeFeature refresh") + debugInfoSync(" effectiveUID: \(state.effectiveUID)") state.isRefreshing = true state.page = 1 state.hasMore = true + state.userInfoError = nil // 重置错误状态 + state.momentsError = nil // 重置错误状态 return .merge( fetchUserInfo(uid: state.effectiveUID), fetchMoments(uid: state.effectiveUID, page: 1, pageSize: state.pageSize) @@ -89,7 +100,49 @@ struct MeFeature { state.isRefreshing = false switch result { case let .success(resp): - let newMoments = resp.data ?? [] + let myMoments = resp.data ?? [] + // 将 MyMomentInfo 转换为 MomentsInfo,并填充用户信息 + let newMoments = myMoments.map { myMoment in + var momentsInfo = myMoment.toMomentsInfo() + // 填充用户信息 + if let userInfo = state.userInfo { + // 使用默认的成员初始化器 + momentsInfo = MomentsInfo( + dynamicId: momentsInfo.dynamicId, + uid: momentsInfo.uid, + nick: userInfo.nick ?? userInfo.nickname ?? "未知用户", + avatar: userInfo.avatar ?? "", + type: momentsInfo.type, + content: momentsInfo.content, + likeCount: momentsInfo.likeCount, + isLike: momentsInfo.isLike, + commentCount: momentsInfo.commentCount, + publishTime: momentsInfo.publishTime, + worldId: momentsInfo.worldId, + status: momentsInfo.status, + playCount: momentsInfo.playCount, + dynamicResList: momentsInfo.dynamicResList, + gender: userInfo.gender, + squareTop: momentsInfo.squareTop, + topicTop: momentsInfo.topicTop, + newUser: userInfo.newUser, + defUser: userInfo.defUser, + scene: momentsInfo.scene, + userVipInfoVO: nil, // UserVipInfoVO 和 UserVipInfo 类型不匹配,暂时设为 nil + headwearPic: userInfo.userHeadwear?.pic, + headwearEffect: userInfo.userHeadwear?.effect, + headwearType: userInfo.userHeadwear?.type, + headwearName: userInfo.userHeadwear?.headwearName, + headwearId: userInfo.userHeadwear?.headwearId, + experLevelPic: userInfo.userLevelVo?.experUrl, + charmLevelPic: userInfo.userLevelVo?.charmUrl, + isCustomWord: momentsInfo.isCustomWord, + labelList: momentsInfo.labelList + ) + } + return momentsInfo + } + if state.page == 1 { state.moments = newMoments } else { @@ -98,8 +151,14 @@ struct MeFeature { state.hasMore = newMoments.count == state.pageSize if state.hasMore { state.page += 1 } state.momentsError = nil + + debugInfoSync("✅ 我的动态加载成功") + debugInfoSync(" 加载数量: \(newMoments.count)") + debugInfoSync(" 总数量: \(state.moments.count)") + debugInfoSync(" 是否有更多: \(state.hasMore)") case let .failure(error): state.momentsError = error.localizedDescription + debugErrorSync("❌ 我的动态加载失败: \(error.localizedDescription)") } return .none case .settingButtonTapped: @@ -118,9 +177,16 @@ struct MeFeature { private func fetchUserInfo(uid: Int) -> Effect { .run { send in + debugInfoSync("👤 开始获取用户信息") + debugInfoSync(" UID: \(uid)") + if let userInfo = await UserInfoManager.fetchUserInfoFromServer(uid: String(uid), apiService: apiService) { + debugInfoSync("✅ 用户信息获取成功") + debugInfoSync(" 昵称: \(userInfo.nick ?? userInfo.nickname ?? "未知")") + debugInfoSync(" 头像: \(userInfo.avatar ?? "无")") await send(.userInfoResponse(.success(userInfo))) } else { + debugErrorSync("❌ 用户信息获取失败") await send(.userInfoResponse(.failure(.noData))) } } @@ -128,11 +194,28 @@ struct MeFeature { private func fetchMoments(uid: Int, page: Int, pageSize: Int) -> Effect { .run { send in + debugInfoSync("🔄 开始获取我的动态") + debugInfoSync(" UID: \(uid)") + debugInfoSync(" 页码: \(page)") + debugInfoSync(" 页大小: \(pageSize)") + do { let req = GetMyDynamicRequest(fromUid: uid, uid: uid, page: page, pageSize: pageSize) + debugInfoSync("📡 发送请求: \(req.endpoint)") + debugInfoSync(" 参数: fromUid=\(uid), uid=\(uid), page=\(page), pageSize=\(pageSize)") + let resp = try await apiService.request(req) + debugInfoSync("✅ API 请求成功") + debugInfoSync(" 响应码: \(resp.code)") + debugInfoSync(" 消息: \(resp.message)") + debugInfoSync(" 数据数量: \(resp.data?.count ?? 0)") + await send(.momentsResponse(.success(resp))) } catch { + debugErrorSync("❌ API 请求失败: \(error.localizedDescription)") + if let apiError = error as? APIError { + debugErrorSync(" API错误类型: \(apiError)") + } await send(.momentsResponse(.failure(error as? APIError ?? .unknown(error.localizedDescription)))) } } diff --git a/yana/Features/RecoverPasswordFeature.swift b/yana/Features/RecoverPasswordFeature.swift index dab1f49..a6c69ec 100644 --- a/yana/Features/RecoverPasswordFeature.swift +++ b/yana/Features/RecoverPasswordFeature.swift @@ -210,21 +210,32 @@ struct ResetPasswordRequest: APIRequestProtocol { let endpoint = "/acc/pwd/resetByEmail" // 新的API端点 let method: HTTPMethod = .POST let includeBaseParameters = true - let queryParameters: [String: String]? var bodyParameters: [String: Any]? { nil } let timeout: TimeInterval = 30.0 + // MARK: - Private Properties + private let email: String + private let code: String + private let newPwd: String + + // MARK: - Computed Properties + var queryParameters: [String: String]? { + return [ + "email": email, + "newPwd": newPwd, // 参数名改为newPwd + "code": code + ] + } + /// 初始化密码重置请求 /// - Parameters: /// - email: DES加密后的邮箱地址 /// - code: 验证码 /// - newPwd: DES加密后的新密码 init(email: String, code: String, newPwd: String) { - self.queryParameters = [ - "email": email, - "newPwd": newPwd, // 参数名改为newPwd - "code": code - ] + self.email = email + self.code = code + self.newPwd = newPwd } } diff --git a/yana/Resources/en.lproj/Localizable.strings b/yana/Resources/en.lproj/Localizable.strings index 0aeda43..d030d8a 100644 --- a/yana/Resources/en.lproj/Localizable.strings +++ b/yana/Resources/en.lproj/Localizable.strings @@ -100,6 +100,7 @@ // MARK: - Feed List "feedList.title" = "Enjoy your Life Time"; "feedList.slogan" = "The disease is like a cruel ruler,\nand time is our most precious treasure.\nEvery moment we live is a victory\nagainst the inevitable."; +"feedList.empty" = "No moments yet"; // MARK: - Feed "feed.title" = "Enjoy your Life Time"; diff --git a/yana/Resources/zh-Hans.lproj/Localizable.strings b/yana/Resources/zh-Hans.lproj/Localizable.strings index 371cb13..a924ffc 100644 --- a/yana/Resources/zh-Hans.lproj/Localizable.strings +++ b/yana/Resources/zh-Hans.lproj/Localizable.strings @@ -97,7 +97,8 @@ "editFeed.enterContent" = "输入内容"; "feedList.title" = "享受您的生活时光"; -"feedList.slogan" = "疾病如同残酷的统治者,\n而时间是我们最宝贵的财富。\n我们活着的每一刻,都是对不可避免命运的胜利。"; +"feedList.slogan" = "疾病如同残酷的统治者,\n而时间是我们最宝贵的财富。\n我们活着的每一刻,都是对不可避免命运的胜利。"; +"feedList.empty" = "暂无动态"; "feed.title" = "享受您的生活时光"; "feed.empty" = "暂无动态内容"; diff --git a/yana/Views/DetailView.swift b/yana/Views/DetailView.swift index 54c1e12..68603f7 100644 --- a/yana/Views/DetailView.swift +++ b/yana/Views/DetailView.swift @@ -23,7 +23,7 @@ struct DetailView: View { WithPerceptionTracking { CustomNavigationBar( title: LocalizedString("detail.title", comment: "Detail page title"), - showDeleteButton: isCurrentUserDynamic, + showDeleteButton: false, isDeleteLoading: store.isDeleteLoading, onBack: { // 移除 onDismiss?() 调用,因为现在使用 dismiss() diff --git a/yana/Views/FeedListView.swift b/yana/Views/FeedListView.swift index ee8a65f..bdfa0f9 100644 --- a/yana/Views/FeedListView.swift +++ b/yana/Views/FeedListView.swift @@ -173,6 +173,13 @@ struct FeedListContentView: View { @Binding var previewCurrentIndex: Int var body: some View { + // 添加调试信息 + let _ = debugInfoSync("📱 FeedListContentView 状态:") + let _ = debugInfoSync(" isLoading: \(store.isLoading)") + let _ = debugInfoSync(" error: \(store.error ?? "nil")") + let _ = debugInfoSync(" moments.count: \(store.moments.count)") + let _ = debugInfoSync(" hasMore: \(store.hasMore)") + if store.isLoading { FeedListLoadingView() } else if let error = store.error { diff --git a/yana/Views/MeView.swift b/yana/Views/MeView.swift index e410ec7..7cde27e 100644 --- a/yana/Views/MeView.swift +++ b/yana/Views/MeView.swift @@ -79,6 +79,11 @@ struct MeView: View { } } .onAppear { + debugInfoSync("📱 MeView onAppear") + debugInfoSync(" 用户信息: \(store.userInfo?.nick ?? "nil")") + debugInfoSync(" 动态数量: \(store.moments.count)") + debugInfoSync(" 用户信息错误: \(store.userInfoError ?? "nil")") + debugInfoSync(" 动态错误: \(store.momentsError ?? "nil")") store.send(.onAppear) } // 新增:图片预览弹窗 @@ -174,7 +179,7 @@ struct MeView: View { .multilineTextAlignment(.center) .padding(.horizontal, 32) Button("重试") { - store.send(.onAppear) + store.send(.refresh) } .font(.system(size: 14, weight: .medium)) .foregroundColor(.white) @@ -192,6 +197,22 @@ struct MeView: View { Text("暂无动态") .font(.system(size: 16, weight: .medium)) .foregroundColor(.white.opacity(0.7)) + // 添加调试信息 + Text("调试: moments.count = \(store.moments.count)") + .font(.system(size: 12)) + .foregroundColor(.yellow) + Text("调试: isLoadingUserInfo = \(store.isLoadingUserInfo)") + .font(.system(size: 12)) + .foregroundColor(.yellow) + Text("调试: isLoadingMoments = \(store.isLoadingMoments)") + .font(.system(size: 12)) + .foregroundColor(.yellow) + Text("调试: userInfoError = \(store.userInfoError ?? "nil")") + .font(.system(size: 12)) + .foregroundColor(.yellow) + Text("调试: momentsError = \(store.momentsError ?? "nil")") + .font(.system(size: 12)) + .foregroundColor(.yellow) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else {