//
|
// YYSpecialCarFlowViewController.swift
|
// OKProject
|
//
|
// Created by alvin_y on 2020/9/17.
|
// Copyright © 2020 yangwang. All rights reserved.
|
//
|
|
import UIKit
|
import RxSwift
|
import RxCocoa
|
|
|
class YYSpecialCarFlowViewController: YYViewController {
|
var complainDriverBlock:(()->())?
|
let viewModel: YYSpecialCarViewModel
|
|
/// 地图控制器
|
let vc_mapView = YYMapViewController()
|
|
/// 司机和行程信息栏
|
let view_travel = YYTravelInfosView.makeByXIB()
|
|
/// 底部状态信息栏
|
let view_state = YYTravelStateView.makeByXIB()
|
|
/// 服务信息
|
let view_service = YYSpecialServiceView.makeByXIB()
|
|
let didPressRefresh = Delegate<Void, Void>()
|
|
var intervalDisposeBag = DisposeBag()
|
|
/// 无人接单提示
|
weak var popupView: YYPopupView?
|
|
/// 跨城下单
|
let isCanleTye = BehaviorRelay<travelType>(value: .orderTravel)
|
lazy var button_canceled: UIButton = {
|
let button = UIButton()
|
button.setTitle("取消订单", for: .normal)
|
button.setTitleColor(.white, for: .normal)
|
button.backgroundColor = #colorLiteral(red: 0.5058823529, green: 0.5098039216, blue: 0.5294117647, alpha: 1)
|
button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
|
button.cornerRadius = 4
|
return button
|
}()
|
|
|
/// 分享行程
|
lazy var button_share: UIButton = {
|
let button = UIButton()
|
button.setTitle("分享", for: .normal)
|
button.setTitleColor(#colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1), for: .normal)
|
button.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
|
button.setImage(#imageLiteral(resourceName: "icon_share"), for: .normal)
|
button.titleLabel?.font = UIFont.systemFont(ofSize: 9, weight: .medium)
|
button.cornerRadius = 4
|
button.shadowColor = #colorLiteral(red: 0.6392156863, green: 0.6235294118, blue: 0.6235294118, alpha: 0.5)
|
button.shadowOffset = CGSize.zero
|
button.shadowRadius = 4
|
button.isHidden = true
|
button.adjustImage(position: .top, spacing: 0)
|
return button
|
}()
|
|
|
var timerDisposeBag = DisposeBag()
|
|
var arrivedTimerDisposeBag = DisposeBag()
|
|
init(viewModel: YYSpecialCarViewModel) {
|
self.viewModel = viewModel
|
super.init(nibName: nil, bundle: nil)
|
}
|
|
required init?(coder aDecoder: NSCoder) {
|
fatalError("init(coder:) has not been implemented")
|
}
|
|
override func viewDidLoad() {
|
super.viewDidLoad()
|
|
// Do any additional setup after loading the view.
|
viewModel.queryPhones()
|
}
|
|
override func setupViews() {
|
super.setupViews()
|
|
title = "等待应答"
|
view_travel.viewModel = self.viewModel
|
|
view.addSubview(vc_mapView.view)
|
|
view.addSubview(view_travel)
|
|
view.addSubview(view_state)
|
|
view.addSubview(button_canceled)
|
|
view.addSubview(view_service)
|
|
view.addSubview(button_share)
|
view_travel.complain_driverBt.rx.tap.subscribe { (r) in
|
// 投诉司机
|
self.complainDriverBlock?()
|
}.disposed(by: rx.disposeBag)
|
|
|
}
|
|
override func defineLayouts() {
|
super.defineLayouts()
|
|
vc_mapView.view.snp.makeConstraints { (make) in
|
make.edges.equalTo(view)
|
}
|
|
view_travel.snp.makeConstraints { (make) in
|
make.top.equalTo(topLayoutGuide.snp.bottom)
|
make.left.right.equalTo(view)
|
}
|
|
view_state.snp.makeConstraints { (make) in
|
make.bottom.equalTo(bottomLayoutGuide.snp.top).offset(-8)
|
make.left.equalTo(view).offset(8)
|
make.right.equalTo(view).offset(-8)
|
}
|
|
button_canceled.snp.makeConstraints { (make) in
|
make.bottom.equalToSuperview().offset(-14)
|
make.left.equalToSuperview().offset(14)
|
make.right.equalToSuperview().offset(-14)
|
make.height.equalTo(40)
|
}
|
|
view_service.snp.makeConstraints { (make) in
|
make.right.equalToSuperview().offset(-14)
|
make.width.equalTo(32)
|
make.bottom.equalToSuperview().offset(-70)
|
}
|
|
button_share.snp.makeConstraints { (make) in
|
make.left.equalToSuperview().offset(14)
|
make.bottom.equalTo(view_state.snp.top).offset(-12)
|
make.size.equalTo(CGSize(width: 32, height: 32))
|
}
|
}
|
|
//MARK: - Rx
|
override func bindRx() {
|
super.bindRx()
|
|
/// 分享
|
button_share
|
.rx.tap
|
.subscribe(onNext: { (_) in
|
// 弹出分享框
|
ShareView.share(controller: self, title: "分享行程", content: "你的好友(\(app.userInfo.phone))正在使用宽窄出行快车(\(self.viewModel.dataSource.value?.licensePlate ?? ""))。", url: "\(share_url)/orderShare/index.html?orderId=\(self.viewModel.orderId.value)&orderType=\(self.viewModel.orderType.value.rawValue)",hiddenMessage: false).show(success: {
|
|
})
|
}).disposed(by: disposeBag)
|
|
view_service.button_position
|
.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
guard let startLat = self.viewModel.dataSource.value?.startLat,let startLon = self.viewModel.dataSource.value?.startLon else{return}
|
self.vc_mapView.mapView.setCenter(CLLocationCoordinate2D.init(latitude: startLat, longitude: startLon), animated: true)
|
})
|
.disposed(by: disposeBag)
|
|
view_service.button_customerService
|
.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
call(number: self.viewModel.complaintsNumber.value)
|
})
|
.disposed(by: disposeBag)
|
|
view_service.button_police
|
.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
call(number: self.viewModel.policeNumber.value)
|
})
|
.disposed(by: disposeBag)
|
|
/// 取消订单
|
button_canceled.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
YYAlertViewController.display(title: "提示", text: "您确定要取消该订单吗?", cancelTitle: "不取消", doneTitle: "确定取消") { [unowned self] in
|
if self.viewModel.dataSource.value?.state == 1{ // 司机未接单 直接取消
|
self.queryCancleAmount()
|
}else{ // 司机已接单 判断需不需要付费
|
let vc = storyBoard(name: "Home", identifier: "TravelServiceCancelVC") as! TravelServiceCancelVC
|
vc.orderType = .special
|
vc.orderId = self.viewModel.orderId.value
|
vc.didPressPay.delegate(on: self) { (self,arge) in
|
let (money,cancleId) = arge
|
self.navigationItem.rightBarButtonItem?.customView?.isHidden = true
|
self.didPressRefresh.call()
|
self.viewModel.amount.accept(money)
|
self.viewModel.cancelId.accept(cancleId)
|
}
|
self.yy_push(vc: vc)
|
}
|
}
|
})
|
.disposed(by: disposeBag)
|
|
/// 更新司机位置
|
YYSocketManager.shared().position
|
.subscribe(onNext: {[unowned self] (r) in
|
guard let data = r.data else{return}
|
if data.orderId == self.viewModel.orderId.value && data.orderType == self.viewModel.orderType.value.rawValue{
|
self.updateDriverLocation(data: data)
|
}
|
}).disposed(by: rx.disposeBag)
|
|
/// 更新司机位置
|
viewModel.driverInfo.subscribe(onNext: {[unowned self] (r) in
|
guard let data = r else {return}
|
if data.state < 7{
|
guard let model = self.viewModel.dataSource.value else{return}
|
if model.driverId == 0{
|
self.didPressRefresh.call()
|
}
|
if data.state == 4{
|
if self.viewModel.dataSource.value?.arriveTime == ""{
|
self.didPressRefresh.call()
|
}
|
}
|
model.state = data.state
|
self.viewModel.state.accept(SpecialCarState(rawValue: data.state) ?? .witingForResponse)
|
}else{
|
self.didPressRefresh.call()
|
}
|
self.updateDriverLocation(data: data)
|
}).disposed(by: disposeBag)
|
|
view_travel.button_call
|
.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
guard let phone = self.viewModel.dataSource.value?.driverPhone else {return}
|
call(number: phone)
|
})
|
.disposed(by: disposeBag)
|
|
view_travel.button_avatar.rx.tap
|
.subscribe(onNext: {[unowned self] (_) in
|
guard let driverId = self.viewModel.dataSource.value?.driverId else{return}
|
let vc = DriverInfoVC(driverId: driverId)
|
self.yy_push(vc: vc)
|
})
|
.disposed(by: disposeBag)
|
|
/// 司机信息
|
viewModel.dataSource
|
.subscribe(onNext: { [unowned self] (dataSource) in
|
self.view_travel.configure(for: dataSource)
|
})
|
.disposed(by: disposeBag)
|
|
/// 监听当前状态
|
viewModel.state
|
.subscribeOn(MainScheduler.instance)
|
.subscribe(onNext: { [unowned self] (state) in
|
|
self.timerDisposeBag = DisposeBag()
|
self.arrivedTimerDisposeBag = DisposeBag()
|
self.vc_mapView.cleanAll()
|
self.vc_mapView.cleanDriverAnnotation()
|
if state == .witingForResponse{
|
self.view_service.snp.remakeConstraints { (make) in
|
make.right.equalToSuperview().offset(-14)
|
make.width.equalTo(32)
|
make.bottom.equalTo(self.button_canceled.snp.top).offset(-12)
|
}
|
}else{
|
self.view_service.snp.remakeConstraints { (make) in
|
make.right.equalToSuperview().offset(-14)
|
make.width.equalTo(32)
|
make.bottom.equalTo(self.view_state.snp.top).offset(-12)
|
}
|
}
|
switch state {
|
case .witingForResponse:
|
self.vc_mapView.setAnnotation(waitingForResponseLocation: self.viewModel.dataSource.value?.startCoordinate())
|
self.fireWaitingForResponseTimer()
|
self.view_travel.view_driverInfos.isHidden = true
|
self.button_canceled.isHidden = false
|
self.view_travel.view_travelInfos.isHidden = false
|
self.view_state.view_state.isHidden = true
|
self.navigationItem.rightBarButtonItem = nil
|
case .driverReaydToGo:
|
self.view_travel.view_driverInfos.isHidden = false
|
self.button_canceled.isHidden = true
|
self.view_travel.view_travelInfos.isHidden = false
|
self.view_state.view_state.isHidden = false
|
self.vc_mapView.setAnnotation(startLocation: self.viewModel.dataSource.value?.startCoordinate(),title: self.viewModel.dataSource.value?.startAddress ?? "")
|
case .witingForPickUp:
|
self.view_travel.view_driverInfos.isHidden = false
|
self.button_canceled.isHidden = true
|
self.view_travel.view_travelInfos.isHidden = false
|
self.view_state.view_state.isHidden = false
|
self.vc_mapView.setAnnotation(startLocation: self.viewModel.dataSource.value?.startCoordinate(),title: self.viewModel.dataSource.value?.startAddress ?? "")
|
case .driverArrived:
|
self.fireArrivedTimer()
|
self.view_travel.view_driverInfos.isHidden = false
|
self.button_canceled.isHidden = true
|
self.view_travel.view_travelInfos.isHidden = false
|
self.view_state.view_state.isHidden = false
|
self.vc_mapView.setAnnotation(startLocation: self.viewModel.dataSource.value?.startCoordinate(),title: self.viewModel.dataSource.value?.startAddress ?? "")
|
case .serving, .waitingForConfirmCost:
|
self.button_share.isHidden = false
|
self.view_travel.view_driverInfos.isHidden = false
|
self.button_canceled.isHidden = true
|
self.view_travel.view_travelInfos.isHidden = false
|
self.view_state.view_state.isHidden = false
|
self.navigationItem.rightBarButtonItem = nil
|
// 起始点
|
guard let startCoordinate = self.viewModel.dataSource.value?.startCoordinate(),let destinationCoordinate = self.viewModel.dataSource.value?.destinationCoordinate() else{return}
|
self.vc_mapView.setAnnotations(startLocation: startCoordinate,destinationLocation: destinationCoordinate,edgePadding: UIEdgeInsets(top: 300, left: 10, bottom: 100, right: 10))
|
default:
|
self.button_share.isHidden = true
|
self.view_travel.view_driverInfos.isHidden = true
|
self.button_canceled.isHidden = true
|
self.view_travel.view_travelInfos.isHidden = true
|
self.view_state.view_state.isHidden = true
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
/// 更新司机位置
|
/// - Parameter data: 数据
|
func updateDriverLocation(data: SocketInfoModel) {
|
if self.viewModel.dataSource.value?.state == 2 || self.viewModel.dataSource.value?.state == 3{
|
self.view_state.label_state.attributedText = self.viewModel.attributedString(state: self.viewModel.dataSource.value?.state ?? 2, data: data)
|
/// 加入司机位置
|
self.vc_mapView.updateAnnotation(driverLocation: CLLocationCoordinate2DMake(data.lat, data.lon))
|
|
if self.viewModel.dataSource.value?.state == 3{
|
guard let startLat = self.viewModel.dataSource.value?.startLat,let startLon = self.viewModel.dataSource.value?.startLon else{return}
|
let startCoordinate = CLLocationCoordinate2DMake(data.lat, data.lon)
|
let destinationCoordinate = CLLocationCoordinate2DMake(startLat, startLon)
|
// 路径规划
|
self.vc_mapView.showPolyline(startCoorninate: startCoordinate, endCoordinate: destinationCoordinate)
|
}
|
}else if self.viewModel.dataSource.value?.state == 4{
|
/// 加入司机位置
|
self.vc_mapView.updateAnnotation(driverLocation: CLLocationCoordinate2DMake(data.lat, data.lon))
|
}else if self.viewModel.dataSource.value?.state == 5 || self.viewModel.dataSource.value?.state == 6{
|
self.view_state.label_state.textAlignment = .center
|
self.view_state.label_state.attributedText = self.viewModel.attributedString(state: self.viewModel.dataSource.value?.state ?? 5, data: data)
|
/// 加入司机位置
|
self.vc_mapView.updateAnnotation(driverLocation: CLLocationCoordinate2DMake(data.lat, data.lon))
|
// 路线规划
|
guard let endLat = self.viewModel.dataSource.value?.endLat,let endLon = self.viewModel.dataSource.value?.endLon else{return}
|
let startCoordinate = CLLocationCoordinate2DMake(data.lat, data.lon)
|
let destinationCoordinate = CLLocationCoordinate2DMake(endLat, endLon)
|
// 路径规划
|
self.vc_mapView.showPolyline(startCoorninate: startCoordinate, endCoordinate: destinationCoordinate)
|
}
|
}
|
|
//MARK: - 取消模块
|
/// 取消订单
|
func queryCancleAmount() {
|
YYAlertKit.displayActivity()
|
viewModel.queryCancleAmount()
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(let data):
|
YYAlertKit.dismiss()
|
guard let data = data else {return}
|
self.viewModel.amount.accept(data.amount)
|
if data.amount == 0{
|
self.addCancledRecord(orderType: viewModel.orderType.value)
|
}else{
|
let vc = storyBoard(name: "Home", identifier: "TravelServiceCancelVC") as! TravelServiceCancelVC
|
vc.orderId = self.viewModel.orderId.value
|
vc.orderType = .special
|
vc.didPressPay.delegate(on: self) { (self,arge) in
|
let (money,cancleId) = arge
|
self.navigationItem.rightBarButtonItem?.customView?.isHidden = true
|
self.didPressRefresh.call()
|
self.viewModel.amount.accept(money)
|
self.viewModel.cancelId.accept(cancleId)
|
}
|
self.yy_push(vc: vc)
|
}
|
break
|
case .failure(let error):
|
YYAlertKit.display(message: error.localizedDescription)
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
/// 添加取消记录
|
func addCancledRecord(orderType:OrderType = .special) {
|
YYAlertKit.displayActivity()
|
viewModel.addCancledRecord(orderType: orderType)
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(_):
|
YYAlertKit.dismiss()
|
// 判断需不需要付费
|
if self.viewModel.amount.value == 0{
|
YYAlertKit.display(message: "取消成功")
|
if self.isCanleTye.value == .commentTravel {
|
// 返回到跨城完成的页面
|
for vc in (self.navigationController?.children)! {
|
if vc.isKind(of: YYSpecialCarViewController.classForCoder()) {
|
self.navigationController?.popToViewController(vc, animated: true)
|
|
}
|
}
|
}else{
|
self.yy_pop()
|
}
|
NotificationCenter.default.post(name: NSNotification.Name.init(YYOrderListRefresh), object: nil)
|
}else{
|
self.addCancled()
|
}
|
break
|
case .failure(let error):
|
YYAlertKit.display(message: error.localizedDescription)
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
|
/// 取消订单
|
func addCancled() {
|
YYAlertKit.displayActivity()
|
viewModel.cancleOrder()
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(_):
|
YYAlertKit.dismiss()
|
YYAlertKit.display(message: "取消成功")
|
self.yy_pop()
|
NotificationCenter.default.post(name: NSNotification.Name.init(YYOrderListRefresh), object: nil)
|
break
|
case .failure(let error):
|
YYAlertKit.display(message: error.localizedDescription)
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
/// 检查订单
|
func queryEndPush() {
|
viewModel.queryEndPush()
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(let data):
|
guard let data = data else {return}
|
if self.viewModel.orderId.value == data.orderId{
|
if data.state == 2{
|
if self.popupView == nil{
|
// 需要弹框
|
self.popupView = YYPopupView.instance(type: .double)
|
self.popupView?.label_title.text = "通知"
|
self.popupView?.label_content.text = "附近暂无司机接单,您是否继续等待?"
|
self.popupView?.button_cancel.setTitle("取消订单", for: .normal)
|
self.popupView?.button_submit.setTitle("继续等待", for: .normal)
|
self.popupView?.button_close.isHidden = false
|
self.popupView?.pressSubmitBlock = {
|
self.pushOrder()
|
}
|
self.popupView?.pressCancelBlock = {
|
self.queryCancleAmount()
|
}
|
app.window?.addSubview(self.popupView!)
|
self.popupView?.show()
|
}
|
}
|
}
|
break
|
case .failure(let error):
|
YYAlertKit.display(message: error.localizedDescription)
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
|
/// 继续等待推单
|
func pushOrder() {
|
YYAlertKit.displayActivity()
|
viewModel.pushOrder()
|
.subscribe(onNext: { (result) in
|
switch result{
|
case .success(_):
|
YYAlertKit.dismiss()
|
break
|
case .failure(let error):
|
YYAlertKit.display(message: error.localizedDescription)
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
//MARK: - 计时器模块
|
/// 启动等待应答倒计时
|
func fireWaitingForResponseTimer() {
|
timerDisposeBag = DisposeBag()
|
Observable<Int>.interval(RxTimeInterval.seconds(1), scheduler: MainScheduler.instance)
|
.subscribe(onNext: { [unowned self] (seconds) in
|
guard let orderTime = self.viewModel.orderTime.value,orderTime != "" else{return}
|
let insertTime = orderTime.toDate(fromFormat: "yyyy-MM-dd HH:mm:ss")
|
guard let date = insertTime else{return}
|
let attributedText = AttributedStringbuilder.build()
|
.add(string: "正为您寻找车辆 等待", withFont: UIFont.systemFont(ofSize: 14, weight: .medium), withColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.8))
|
.add(string: "\(calculateWaitTime(time: date.timeIntervalSince1970))", withFont: UIFont.systemFont(ofSize: 14, weight: .medium), withColor: #colorLiteral(red: 0.8901960784, green: 0.0431372549, blue: 0.0431372549, alpha: 1))
|
.mutableAttributedString
|
self.vc_mapView.waitingForResponseAnnotationView?.label_title.attributedText = attributedText
|
})
|
.disposed(by: timerDisposeBag)
|
}
|
|
|
/// 司机已到达
|
func fireArrivedTimer() {
|
arrivedTimerDisposeBag = DisposeBag()
|
Observable<Int>.interval(RxTimeInterval.seconds(1), scheduler: MainScheduler.instance)
|
.subscribe(onNext: { [unowned self] (seconds) in
|
let arriveTime = self.viewModel.dataSource.value?.arriveTime.toDate(fromFormat: "yyyy-MM-dd HH:mm:ss")
|
guard let date = arriveTime else{return}
|
let text = calculateWaitTime(time: date.timeIntervalSince1970)
|
self.view_state.label_state.textAlignment = .center
|
self.view_state.label_state.attributedText = AttributedStringbuilder.build().add(string: "司机到达预约地点,已等您", withFont: UIFont.init(name: Medium, size: 14)!, withColor: UIColor.color(hexString: "#333333"))
|
.add(string: text, withFont: UIFont.init(name: Medium, size: 14)!, withColor: ThemeColor)
|
.mutableAttributedString
|
})
|
.disposed(by: arrivedTimerDisposeBag)
|
|
}
|
}
|