116 lines
3.4 KiB
Swift
116 lines
3.4 KiB
Swift
//
|
||
// 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<String, SchedulePointItem>
|
||
|
||
class CreateScheduleVM {
|
||
|
||
let disposeBag = DisposeBag()
|
||
|
||
let scheduModel: ScheduleModel?
|
||
|
||
// MARK: - Input
|
||
let addPointTapped = PublishSubject<Void>()
|
||
let deletePointAt = PublishSubject<Int>()
|
||
let updatePoint = PublishSubject<(index: Int, item: SchedulePointItem)>()
|
||
let selectedDate = BehaviorRelay<Date>(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<String>
|
||
|
||
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)
|
||
}
|
||
|
||
}
|