// // GroupViewModel.swift // QuickLocation // import Foundation import RxSwift import RxCocoa import RxDataSources import OpenIMSDK typealias HotGroupListSectionModel = SectionModel typealias CircleListSectionModel = SectionModel /// 群聊 cell 数据(融合群信息 + 会话信息) struct GroupCellData { let groupInfo: OIMGroupInfo let unreadCount: Int let lastMsgTime: Int // ms timestamp let localIcon: UIImage } final class GroupViewModel { struct Output { let hotGroups: Observable<[HotGroupListSectionModel]> let createdSections: Observable<[CircleListSectionModel]> let joinedSections: Observable<[CircleListSectionModel]> let segmentTitles: Driver<[String]> } let output: Output private let hotGroupSectionedItems = PublishSubject<[HotGroupListSectionModel]>() private let createdSectionsSubject = PublishSubject<[CircleListSectionModel]>() private let joinedSectionsSubject = PublishSubject<[CircleListSectionModel]>() let segmentTitles = BehaviorRelay<[String]>(value: ["我创建的圈子", "我加入的圈子"]) var groupList: [GroupInfoModel] = [] private var cachedGroups: [OIMGroupInfo] = [] private var cachedConversations: [OIMConversationInfo] = [] /// 当前群的本地图标 func getLocalIcon(groupId: String) -> UIImage { groupList.first { groupId == $0.group_key }?.groupIcon ?? UIImage(named: "GroupIcon/1")! } /// 热门酷圈 func loadHotGroupData(_ list: [GroupInfoModel]) { hotGroupSectionedItems.onNext(list.mapSection()) } /// 加载群列表(全量刷新) func loadIMGroups(_ groups: [OIMGroupInfo], conversations: [OIMConversationInfo] = []) { if !groups.isEmpty { cachedGroups = groups } if !conversations.isEmpty { cachedConversations = conversations } reloadData() } /// 仅更新会话元数据(未读、时间)- 消息监听回调(只返回变更的会话,需合并) func updateConversations(_ conversations: [OIMConversationInfo]) { var merged: [String: OIMConversationInfo] = [:] for c in cachedConversations { if let gid = c.groupID { merged[gid] = c } } for c in conversations { if let gid = c.groupID { merged[gid] = c } } cachedConversations = Array(merged.values) reloadData() } private func reloadData() { let currentUserId = AppContextManager.shared.userId let convMap: [String: OIMConversationInfo] = { var m: [String: OIMConversationInfo] = [:] for c in cachedConversations where c.groupID != nil && !(c.groupID?.isEmpty ?? true) { m[c.groupID!] = c } return m }() var created: [GroupCellData] = [] var joined: [GroupCellData] = [] for g in cachedGroups { let conv = convMap[g.groupID ?? ""] let data = GroupCellData( groupInfo: g, unreadCount: Int(conv?.unreadCount ?? 0), lastMsgTime: Int(conv?.latestMsgSendTime ?? 0), localIcon: getLocalIcon(groupId: g.groupID ?? "") ) if g.ownerUserID == currentUserId || g.creatorUserID == currentUserId { created.append(data) } else { joined.append(data) } } createdSectionsSubject.onNext(created.mapSection()) joinedSectionsSubject.onNext(joined.mapSection()) } // MARK: - Init init() { output = Output( hotGroups: hotGroupSectionedItems.asObservable(), createdSections: createdSectionsSubject.asObservable(), joinedSections: joinedSectionsSubject.asObservable(), segmentTitles: segmentTitles.asDriver() ) } }