// // CreateScheduleVM.swift // QuickLocation // // Created by 八条 on 2026/6/24. // import RxSwift import RxCocoa import RxDataSources // MARK: - 行程点编辑模型 struct SchedulePointItem: IdentifiableType, Equatable { let identity: String = UUID().uuidString var locationName: String = "" var address: String = "" var latitude: Double = 0 var longitude: Double = 0 var province: String = "" var city: String = "" var district: String = "" var street: String = "" var country: String = "" var formatted_address: String = "" var expectedTime: Date? var remark: String = "" } typealias SchedulePointSection = SectionModel class CreateScheduleVM { let disposeBag = DisposeBag() let scheduModel: ScheduleModel? // MARK: - Input let addPointTapped = PublishSubject() let deletePointAt = PublishSubject() let updatePoint = PublishSubject<(index: Int, item: SchedulePointItem)>() let selectedDate = BehaviorRelay(value: Date()) var selectedGroupKeys: [String] = [] /// 切换圈子选中状态(已选则删除,未选则添加) func toggleGroupKey(_ key: String) { if let idx = selectedGroupKeys.firstIndex(of: key) { selectedGroupKeys.remove(at: idx) } else { selectedGroupKeys.append(key) } } /// 删除指定圈子 key func removeGroupKey(_ key: String) { selectedGroupKeys.removeAll { $0 == key } } // MARK: - Output let pointsRelay: BehaviorRelay<[SchedulePointItem]> let dateString: Observable init(_ model: ScheduleModel?) { self.scheduModel = model // 编辑模式:从 model 回显数据 if let m = model, !m.points.isEmpty { pointsRelay = BehaviorRelay<[SchedulePointItem]>(value: m.points.map { $0.toSchedulePointItem() }) selectedDate.accept(Date(timeIntervalSince1970: TimeInterval(m.timestamp) / 1000)) selectedGroupKeys = m.groups.map { $0.group_key } } else { pointsRelay = BehaviorRelay<[SchedulePointItem]>(value: [SchedulePointItem()]) } dateString = selectedDate .map { let fmt = DateFormatter() fmt.dateFormat = "yyyy年MM月dd日" return fmt.string(from: $0) } // 添加行程点 addPointTapped .withLatestFrom(pointsRelay) .map { list in var new = list new.append(SchedulePointItem()) return new } .bind(to: pointsRelay) .disposed(by: disposeBag) // 删除行程点 deletePointAt .withLatestFrom(pointsRelay) { ($1, $0) } .subscribe(onNext: { list, idx in guard list.count > 1, idx < list.count else { return } var new = list new.remove(at: idx) self.pointsRelay.accept(new) }) .disposed(by: disposeBag) // 更新某个行程点 updatePoint .withLatestFrom(pointsRelay) { ($1, $0) } .subscribe(onNext: { list, update in guard update.index < list.count else { return } var new = list new[update.index] = update.item self.pointsRelay.accept(new) }) .disposed(by: disposeBag) } }