// // ScheduleVC.swift // QuickLocation // // Created by 八条 on 2026/6/23. // import UIKit import RxSwift import RxCocoa import RxDataSources import MJRefresh import ObjectMapper class ScheduleVC: BaseViewController { fileprivate var rootView: ScheduleView! override func loadView() { rootView = ScheduleView(frame: UIScreen.main.bounds) view = rootView } private var viewModel = ScheduleViewModel() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. rootView.allCheckBtn.isSelected = true setupTableViewHeaderFooter() bindViewModel() reactiveAction() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) requestFollowList() requestData() } private func bindViewModel() { viewModel.output.sectionedItems .bind(to: rootView.collectionView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) viewModel.output.scheduleSectionedItems .bind(to: rootView.tableView.rx.items(dataSource: tableViewDataSource)) .disposed(by: disposeBag) viewModel.output.refreshResult.subscribe(onNext: { [weak self] (status, isEmpty) in guard let self = self else { return } self.dl.dismiss() self.rootView.tableView.refresh(status: status, isEmpty: isEmpty) }).disposed(by: disposeBag) rootView.collectionView.rx.modelSelected(ViewedModel.self) .subscribe(viewModel.viewedCellAction.inputs) .disposed(by: disposeBag) rootView.tableView.rx.modelSelected(ScheduleModel.self) .subscribe(viewModel.cellAction.inputs) .disposed(by: disposeBag) } private func reactiveAction() { // 全部 rootView.allCheckBtn.rx.tap.subscribe(onNext: { [weak self] _ in guard let self = self, !self.rootView.allCheckBtn.isSelected else { return } self.rootView.allCheckBtn.isSelected = true self.rootView.followedCheckBtn.isSelected = false self.rootView.mineCheckBtn.isSelected = false self.changeCondition(follow: false, own: false) }).disposed(by: disposeBag) // 我关注的 rootView.followedCheckBtn.rx.tap.subscribe(onNext: { [weak self] _ in guard let self = self, !self.rootView.followedCheckBtn.isSelected else { return } self.rootView.allCheckBtn.isSelected = false self.rootView.followedCheckBtn.isSelected = true self.rootView.mineCheckBtn.isSelected = false self.changeCondition(follow: true, own: false) }).disposed(by: disposeBag) // 我的 rootView.mineCheckBtn.rx.tap.subscribe(onNext: { [weak self] _ in guard let self = self, !self.rootView.mineCheckBtn.isSelected else { return } self.rootView.allCheckBtn.isSelected = false self.rootView.followedCheckBtn.isSelected = false self.rootView.mineCheckBtn.isSelected = true self.changeCondition(follow: false, own: true) }).disposed(by: disposeBag) } private func setupTableViewHeaderFooter() { // 设置刷新header/footer let header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in self?.viewModel.refresh() }) header.addFeedbackGenerator() header.stateLabel?.isHidden = true rootView.tableView.mj_header = header let footer = MJRefreshAutoNormalFooter(refreshingBlock: viewModel.loadMore) footer.isHidden = true rootView.tableView.mj_footer = footer } // MARK: - API private func requestFollowList() { DLToast.showLoading() UserService.followList().subscribe(onNext: { response in DLToast.dismiss() self.viewModel.loadViewedData(response.list) }).disposed(by: disposeBag) } private func requestSetFollow(id: String, op: Bool) { DLToast.showLoading() ItineraryService.follow(id: id, op: op ? 2 : 1).subscribe(onNext: { response in DLToast.dismiss() DLToast.show(text: op ? "已取消" : "已关注此行程, \n行程路线将自动添加到您的行程列表。") self.requestData() }).disposed(by: disposeBag) } // MARK: - API 行程列表 private func requestData() { viewModel.refresh() } // 更换查询条件 private func changeCondition(follow: Bool, own: Bool) { viewModel.changeCondition(follow: follow, own: own) requestData() } // MARK: - dataSource private lazy var dataSource: RxCollectionViewSectionedReloadDataSource = { RxCollectionViewSectionedReloadDataSource { datasource, collectionView, indexPath, model in let cell: ViewedCell = collectionView.dequeueReusableCell(for: indexPath) cell.configure(model) return cell } }() // MARK: - UITableViewDataSource lazy private var tableViewDataSource: RxTableViewSectionedReloadDataSource = { return RxTableViewSectionedReloadDataSource( configureCell: { (_, tableView, indexPath, model) in let cell: ScheduleListPopCell = tableView.dequeueReusableCell(for: indexPath) cell.configure(model) // 编辑 cell.editBtn.rx.tap.subscribe(onNext: { _ in AppRouter.push(Route.createSchedule, userInfo: ["scheduleJson": model.toJSON()]) }).disposed(by: cell.disposeBag) // 关注 cell.followBtn.rx.tap.subscribe(onNext: { _ in self.requestSetFollow(id: model.id, op: cell.followBtn.isSelected) }).disposed(by: cell.disposeBag) return cell } ) }() }