import Foundation import ComposableArchitecture // MARK: - 响应数据模型 /// 最新动态响应结构 struct MomentsLatestResponse: Codable, Equatable { let code: Int let message: String let data: MomentsListData? let timestamp: Int? } /// 动态列表数据 struct MomentsListData: Codable, Equatable { let dynamicList: [MomentsInfo] let nextDynamicId: Int } /// 动态信息结构 struct MomentsInfo: Codable, Equatable { let dynamicId: Int let uid: Int let nick: String let avatar: String let gender: Int let type: Int let content: String let likeCount: Int let isLike: Bool let commentCount: Int let publishTime: Int let worldId: Int let squareTop: Int let topicTop: Int let newUser: Bool let defUser: Int let status: Int let scene: String let dynamicResList: [MomentsPicture]? let userVipInfoVO: UserVipInfo? // 头饰相关 - 全部可选 let headwearPic: String? let headwearEffect: String? let headwearType: Int? let headwearName: String? let headwearId: Int? // 等级相关 - 全部可选 let experLevelPic: String? let charmLevelPic: String? // 其他可选字段 let isCustomWord: Bool? let labelList: [String]? // 计算属性:将Int转换为Bool var isSquareTop: Bool { squareTop != 0 } var isTopicTop: Bool { topicTop != 0 } // 计算属性:格式化时间戳 var formattedPublishTime: Date { Date(timeIntervalSince1970: TimeInterval(publishTime) / 1000.0) } } /// 动态图片信息 struct MomentsPicture: Codable, Equatable { let id: Int let resUrl: String let format: String let width: Int let height: Int let resDuration: Int? // 可选字段,因为有些图片没有这个字段 } /// 用户VIP信息 - 完整版本,所有字段都是可选的 struct UserVipInfo: Codable, Equatable { let vipLevel: Int? let vipName: String? let vipIcon: String? let vipLogo: String? let nameplateId: Int? let nameplateUrl: String? let userCardBG: String? let expireTime: Int? let preventKick: Bool? let preventTrace: Bool? let preventFollow: Bool? let micNickColour: String? let micCircle: String? let enterRoomEffects: String? let medalSeat: Int? let friendNickColour: String? let visitHide: Bool? let visitListView: Bool? let privateChatLimit: Bool? let roomPicScreen: Bool? let uploadGifAvatar: Bool? let enterHide: Bool? } // MARK: - 内容类型枚举 /// 动态内容类型 enum MomentsContentType: Int, CaseIterable { case text = 0 // 纯文字 case picture = 2 // 图片 /// 转换为API参数字符串 static func toAPIParameter(_ types: [MomentsContentType]) -> String { return types.map { String($0.rawValue) }.joined(separator: ",") } } // MARK: - 最新动态 API 请求 /// 获取最新动态列表的API请求 struct LatestDynamicsRequest: APIRequestProtocol { typealias Response = MomentsLatestResponse let endpoint: String = APIEndpoint.latestDynamics.path let method: HTTPMethod = .GET let dynamicId: String let pageSize: Int let types: [MomentsContentType] /// 初始化请求 /// - Parameters: /// - dynamicId: 最新动态的ID,用于分页加载。首次请求传空字符串 /// - pageSize: 每页返回的数据数量,默认20 /// - types: 动态内容类型数组,默认包含文字和图片 init( dynamicId: String = "", pageSize: Int = 20, types: [MomentsContentType] = [.text, .picture] ) { self.dynamicId = dynamicId self.pageSize = pageSize self.types = types } var queryParameters: [String: String]? { return [ "dynamicId": dynamicId, "pageSize": String(pageSize), "types": MomentsContentType.toAPIParameter(types) ] } var bodyParameters: [String: Any]? { nil } var includeBaseParameters: Bool { true } // Loading 配置 var shouldShowLoading: Bool { true } var shouldShowError: Bool { true } }