// // 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() // 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() { 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) } /// 从 LocationPicker 回调更新某个点的位置 func updatePointLocation(index: Int, name: String, address: String) { var list = pointsRelay.value guard index < list.count else { return } list[index].locationName = name list[index].address = address pointsRelay.accept(list) } }