// // HomeViewModel.swift // QuickLocation // // Created by 八条 on 2026/5/30. // import RxSwift import RxDataSources import ObjectMapper typealias GroupMemberListSectionModel = SectionModel class HomeViewModel { struct Output { var sectionedItems: Observable<[GroupMemberListSectionModel]> } let output: Output private var disposeBag = DisposeBag() private let sectionedItems = PublishSubject<[GroupMemberListSectionModel]>() lazy var cellAction: Action = { this in return Action { model in return .empty() } }(self) var targetUid: String = "" var groupModel: GroupModel? { didSet { guard let model = groupModel else { return } setMemberList(model.select_group_employee) } } // 当前选中的圈子 var groupInfo: [String: Any] { get { guard let model = groupModel, let groupInfoModel = model.groups.first(where: { $0.group_key == model.default_group_key }) else { return [:] } return groupInfoModel.toJSON() } } // 圈子名字 var groupName: String { get { guard let model = groupModel else { return "我的圈子" } return model.groups.first(where: { $0.group_key == model.default_group_key })?.name ?? "" } } // 圈子成员数 var memberCount: Int { get { guard let model = groupModel else { return 0 } return model.select_group_employee.count } } // 圈子成员在线数 var memberOnlineCount: Int { get { guard let model = groupModel else { return 0 } return model.select_group_employee.filter { $0.is_online == true}.count } } // 是否当前用户 func isCurrentUser(id: String) -> Bool { id == AppContextManager.shared.userId } // 是否圈主 func isGroupOwn(id: String) -> Bool { guard let model = groupModel else { return false } return model.default_group_key.contains(id) } func getUserNickName(id: String) -> String { memberList.first { $0.user_id == id }?.nick_name ?? "" } private(set) var memberList: [GroupMemberModel] = [] private func setMemberList(_ list: [GroupMemberModel]) { memberList = sortedMemberList(list) sectionedItems.onNext(memberList.mapSection()) } private func sortedMemberList(_ list: [GroupMemberModel]) -> [GroupMemberModel] { // 排列顺序:圈主 -> 自己 -> 在线;同优先级保持接口原始顺序 list.enumerated() .sorted { lhs, rhs in let lhsPriority = memberSortPriority(lhs.element) let rhsPriority = memberSortPriority(rhs.element) if lhsPriority != rhsPriority { return lhsPriority < rhsPriority } return lhs.offset < rhs.offset } .map(\.element) } private func memberSortPriority(_ member: GroupMemberModel) -> Int { if isGroupOwn(id: member.user_id) { return 0 } if member.user_id == AppContextManager.shared.userId { return 1 } if member.is_online { return 2 } return 3 } /// 标记成员离线(保留 last_active_time 用于显示"X分钟前") func setMemberOffline(userId: String) { guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return } var updated = memberList updated[idx].is_online = false setMemberList(updated) } /// MQTT 位置更新后刷新成员的地址、电量、在线状态 func updateMemberLocation(userId: String, lat: Double, lon: Double, address: String, battery: String, isOnline: Bool, lastUpdateTime: Int64) { guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return } var updated = memberList updated[idx].last_position = "\(lat):\(lon):\(address)" updated[idx].battery = battery updated[idx].is_online = isOnline updated[idx].last_active_time = lastUpdateTime setMemberList(updated) } /// 成员是否存在 func memberIsExist(userId: String) -> Bool { (memberList.first(where: { $0.user_id == userId }) != nil) } /// 移除成员 func removeMember(userId: String) { guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return } var updated = memberList updated.remove(at: idx) setMemberList(updated) } func updateMemberStatus(userId: String, status: Int) { guard let index = memberList.firstIndex(where: { $0.user_id == userId }) else { return } memberList[index].status = status sectionedItems.onNext(memberList.mapSection()) } // MARK: - Init init() { output = Output( sectionedItems: sectionedItems.asObservable() ) } }