//
|
// YYCarpoolingCarFlowViewController.swift
|
// OKProject
|
//
|
// Created by 无故事王国 on 2022/5/24.
|
// Copyright © 2022 yangwang. All rights reserved.
|
//
|
|
import UIKit
|
import RxSwift
|
import RxCocoa
|
import AMapSearchKit
|
|
/// 拼车流程
|
class YYSpecialCarpoolingCarFlowViewController: 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 tableView:CustomTableView = {
|
let t = CustomTableView(frame: .zero, style: .grouped)
|
t.contentInset = UIEdgeInsets(top: 240, left: 0, bottom: 0, right: 0)
|
t.separatorStyle = .none
|
t.showsVerticalScrollIndicator = false
|
t.register(TableHeaderView.self, forHeaderFooterViewReuseIdentifier: "headerView")
|
t.register(UINib(nibName: "YYSpecialCarpoolingCarTCell", bundle: nil), forCellReuseIdentifier: "_YYSpecialCarpoolingCarTCell")
|
t.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "footView")
|
t.backgroundColor = .clear
|
return t
|
}()
|
|
let hintL:UILabel = {
|
let l = UILabel()
|
l.font = UIFont.systemFont(ofSize: 14, weight: .medium)
|
l.borderColor = UIColor(hexString: "#00BF30")!
|
l.textColor = UIColor(hexString: "#00BF30")
|
l.numberOfLines = 2
|
l.text = "等待接驾"
|
l.textAlignment = .center
|
l.borderWidth = 1
|
l.cornerRadius = 4
|
return l
|
}()
|
|
let didPressRefresh = Delegate<Void, Void>()
|
|
private var userLocationView: LocationAnnotationView?
|
private var currentIndex = -1
|
|
/// 用户点数据
|
private var pointArray: [CarpoolPointAnnotation] = []
|
private var searchAPI:AMapSearchAPI?
|
/// 路线数据
|
private var pathPolylines: [MAOverlay] = []
|
var tempWaypoints = [AMapGeoPoint]()
|
private var currIndex:Int?
|
private var driverLocation:CLLocationCoordinate2D?
|
|
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 carpoolingItems = [YYSpecialCarCarpoolingModel]()
|
|
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()
|
viewModel.queryPhones()
|
}
|
|
override func viewDidAppear(_ animated: Bool) {
|
super.viewDidAppear(animated)
|
}
|
|
override func setupViews() {
|
super.setupViews()
|
|
title = "等待应答"
|
view_travel.viewModel = self.viewModel
|
|
view.addSubview(vc_mapView.view)
|
vc_mapView.isCarpool = true
|
|
view.addSubview(view_travel)
|
|
// view.addSubview(view_state)
|
|
view.addSubview(button_canceled)
|
|
view.addSubview(view_service)
|
|
view.addSubview(button_share)
|
|
view.addSubview(tableView)
|
tableView.delegate = self
|
tableView.dataSource = self
|
tableView.isHidden = true
|
|
view_travel.complain_driverBt.rx.tap.subscribe { (r) in
|
// 投诉司机
|
self.complainDriverBlock?()
|
}.disposed(by: rx.disposeBag)
|
|
createHeadView()
|
// addAnnotations()
|
}
|
|
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)
|
make.height.greaterThanOrEqualTo(0)
|
}
|
|
// 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.top.equalTo(view_travel.snp.bottom)
|
// make.bottom.equalToSuperview().offset(-70)
|
}
|
|
button_share.snp.makeConstraints { (make) in
|
make.left.equalToSuperview().offset(14)
|
make.bottom.equalToSuperview().offset(-12)
|
make.bottom.equalToSuperview().offset(-169)
|
make.size.equalTo(CGSize(width: 32, height: 32))
|
}
|
|
|
tableView.snp.makeConstraints { make in
|
make.left.right.bottom.equalToSuperview()
|
make.top.equalTo(view_travel.bottom).offset(209)
|
}
|
|
|
}
|
|
private func createHeadView(){
|
let containerHeadView = UIView()
|
containerHeadView.backgroundColor = .white
|
containerHeadView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: 68)
|
containerHeadView.addSubview(hintL)
|
hintL.snp.makeConstraints { make in
|
make.center.equalToSuperview()
|
make.left.equalTo(24)
|
make.right.equalTo(-24)
|
make.height.greaterThanOrEqualTo(40)
|
}
|
tableView.tableHeaderView = containerHeadView
|
}
|
|
/// 绘画:每个点位的信息
|
// private func addAnnotations(){
|
//
|
// /// 我
|
// let ani1 = CarpoolPointAnnotation()
|
// ani1.coordinate = CLLocationCoordinate2DMake(30.591706, 104.061045)
|
// ani1.title = "你的起点"
|
// ani1.pointType = .me
|
// self.pointArray.append(ani1)
|
//
|
// let ani2 = CarpoolPointAnnotation()
|
// ani2.coordinate = CLLocationCoordinate2DMake(30.591694, 104.061732)
|
// ani2.title = "尾号:3501起点"
|
// ani2.pointType = .other
|
// self.pointArray.append(ani2)
|
//
|
// let ani3 = CarpoolPointAnnotation()
|
// ani3.coordinate = CLLocationCoordinate2DMake(30.591721, 104.063093)
|
// ani3.title = "尾号:3502起点"
|
// ani3.pointType = .other
|
// self.pointArray.append(ani3)
|
//
|
// let ani4 = CarpoolPointAnnotation()
|
// ani4.coordinate = CLLocationCoordinate2DMake(30.59181, 104.064916)
|
// ani4.title = "尾号:3503起点"
|
// ani4.pointType = .driver
|
// self.pointArray.append(ani4)
|
//
|
// vc_mapView.mapView.addAnnotations(self.pointArray)
|
// startRoteSearch(values: self.pointArray)
|
// }
|
|
/// 发起路线规划
|
// private func startRoteSearch(values:[CarpoolPointAnnotation]){
|
//
|
// let request = AMapDrivingRouteSearchRequest()
|
// var tempWaypoints = [AMapGeoPoint]()
|
// for (index,v) in values.enumerated(){
|
// if index == 0{
|
// request.origin = AMapGeoPoint.location(withLatitude:v.coordinate.latitude, longitude: v.coordinate.longitude)
|
// }else if index == (values.count - 1){
|
// request.destination = AMapGeoPoint.location(withLatitude:v.coordinate.latitude, longitude: v.coordinate.longitude)
|
// }else{
|
// tempWaypoints.append(AMapGeoPoint.location(withLatitude:v.coordinate.latitude, longitude: v.coordinate.longitude))
|
// }
|
// }
|
// request.waypoints = tempWaypoints
|
// vc_mapView.search.aMapDrivingRouteSearch(request)
|
// }
|
|
|
//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)
|
}
|
|
//更新列表
|
viewModel.getOrderDetails()
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(let data):
|
guard let data = data else {return}
|
self.updateLine(data)
|
|
break
|
case .failure(_):break
|
}
|
}).disposed(by: disposeBag)
|
|
|
}).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)
|
if driverLocation != nil{
|
self.vc_mapView.updateAnnotation(driverLocation: self.driverLocation!)
|
}
|
})
|
.disposed(by: disposeBag)
|
|
/// 监听当前状态
|
viewModel.state
|
.subscribeOn(MainScheduler.instance)
|
.subscribe(onNext: { [unowned self] (state) in
|
|
//更新列表
|
viewModel.getOrderDetails()
|
.subscribe(onNext: {[unowned self] (result) in
|
switch result{
|
case .success(let data):
|
guard let data = data else {return}
|
self.updateLine(data)
|
|
break
|
case .failure(_):break
|
}
|
}).disposed(by: disposeBag)
|
|
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.top.equalTo(view_travel.snp.bottom).offset(97)
|
}
|
}else{
|
self.view_service.snp.remakeConstraints { (make) in
|
make.right.equalToSuperview().offset(-14)
|
make.width.equalTo(32)
|
make.top.equalTo(view_travel.snp.bottom).offset(97)
|
}
|
}
|
switch state {
|
case .witingForResponse:
|
self.vc_mapView.setAnnotation(waitingForResponseLocation: self.viewModel.dataSource.value?.startCoordinate())
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
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
|
self.tableView.isHidden = true
|
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 ?? "")
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
self.tableView.isHidden = false
|
case .witingForPickUp: //等待接驾(待到达预约地点)
|
self.updateLine()
|
// self.hintL.text = "司机正在接你"
|
// self.hintL.attributedText = viewModel.attributedString(state: state.rawValue, data: SocketInfoModel)
|
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 ?? "")
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
self.tableView.isHidden = false
|
case .driverArrived: //司机已到达
|
self.updateLine()
|
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 ?? "")
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
self.tableView.isHidden = false
|
case .serving, .waitingForConfirmCost:
|
self.updateLine()
|
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))
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
self.tableView.isHidden = false
|
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
|
self.tableView.isHidden = true
|
break
|
}
|
})
|
.disposed(by: disposeBag)
|
}
|
|
func updateLine(_ model:YYSpecialCarModel? = nil){
|
var dataSource = viewModel.dataSource.value
|
if model != nil{
|
dataSource = model
|
}
|
|
if dataSource?.state ?? 0 >= 2{
|
self.removeOverlays()
|
self.pointArray.removeAll()
|
self.carpoolingItems.removeAll()
|
self.tempWaypoints.removeAll()
|
if self.carpoolingItems.count == 0{
|
|
self.carpoolingItems.append(contentsOf: dataSource?.meetOrderList ?? []) //接
|
self.carpoolingItems.append(contentsOf: dataSource?.giveOrderList ?? []) //送
|
currentIndex = 0
|
//2: 准备(接送),3,4:正在(接送)5:已上车(接),送, 6:送达,7:待支付,8-9完成
|
for (index,item) in (dataSource?.meetOrderList ?? []).enumerated() {
|
if item.orderState.rawValue >= 3{
|
currentIndex = index
|
}
|
}
|
|
for (index,item) in (dataSource?.giveOrderList ?? []).enumerated() {
|
|
if item.orderState.rawValue >= 3{
|
currentIndex += 1
|
}
|
}
|
|
|
if (dataSource?.meetOrderList.count ?? 0) > 0 && (dataSource?.giveOrderList.count ?? 0) > 0{
|
if (dataSource?.meetOrderList.last?.orderState.rawValue)! <= 4{
|
for item in dataSource!.meetOrderList {
|
let ani = CarpoolPointAnnotation()
|
ani.coordinate = CLLocationCoordinate2DMake(item.startLat, item.startLon)
|
ani.title = item.userId == readUser().id ? "你的起点":"尾号\(item.phone.substring(from: 7))起点"
|
ani.pointType = item.userId == readUser().id ? .me:.other
|
ani.isStart = true
|
self.pointArray.append(ani)
|
self.tempWaypoints.append(AMapGeoPoint.location(withLatitude: ani.coordinate.latitude, longitude: ani.coordinate.longitude))
|
}
|
}else{
|
for item in dataSource!.giveOrderList {
|
let ani = CarpoolPointAnnotation()
|
ani.coordinate = CLLocationCoordinate2DMake(item.endLat, item.endLon)
|
ani.title = item.userId == readUser().id ? "你的终点":"尾号\(item.phone.substring(from: 7))终点"
|
ani.pointType = item.userId == readUser().id ? .me:.other
|
ani.isStart = false
|
self.pointArray.append(ani)
|
self.tempWaypoints.append(AMapGeoPoint.location(withLatitude: ani.coordinate.latitude, longitude: ani.coordinate.longitude))
|
}
|
}
|
}
|
|
if driverLocation != nil{
|
let ani = CarpoolPointAnnotation()
|
ani.coordinate = self.driverLocation!
|
ani.title = "司机"
|
ani.pointType = .driver
|
self.pointArray.append(ani)
|
}
|
}
|
self.tableView.reloadData()
|
}
|
|
}
|
|
/// 更新司机位置
|
/// - Parameter data: 数据
|
func updateDriverLocation(data: SocketInfoModel) {
|
|
if self.pointArray.count != 0{
|
self.vc_mapView.mapView.addAnnotations(self.pointArray)
|
}
|
|
self.driverLocation = CLLocationCoordinate2DMake(data.lat, data.lon)
|
|
if self.viewModel.dataSource.value?.state == 2 || self.viewModel.dataSource.value?.state == 3{
|
// self.hintL.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,geoPoints: self.tempWaypoints)
|
}
|
}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.hintL.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,geoPoints: self.tempWaypoints)
|
}
|
}
|
|
//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 removeOverlays() {
|
if pathPolylines.count > 0{
|
vc_mapView.mapView.removeOverlays(pathPolylines)
|
pathPolylines.removeAll()
|
}
|
}
|
|
|
/// 继续等待推单
|
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
|
self.hintL.attributedText = AttributedStringbuilder.build().add(string: "司机到达预约地点,已等您", withFont: UIFont.init(name: Medium, size: 14)!, withColor: ThemeColor)
|
.add(string: text, withFont: UIFont.init(name: Medium, size: 14)!, withColor: UIColor(hexString: "#FB692A")!)
|
.mutableAttributedString
|
})
|
.disposed(by: arrivedTimerDisposeBag)
|
}
|
}
|
|
extension YYSpecialCarpoolingCarFlowViewController:UITableViewDelegate{
|
|
}
|
|
extension YYSpecialCarpoolingCarFlowViewController:UITableViewDataSource{
|
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
let headView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerView") as! TableHeaderView
|
if viewModel.dataSource.value?.spellSuccess == 0{
|
headView.startRotationAni()
|
}else{
|
let num = (viewModel.dataSource.value?.meetOrderList.count ?? 1) - 1
|
headView.setTitle("\(num)位拼友同行")
|
headView.stopRotationAni()
|
}
|
return headView
|
}
|
|
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
|
var footView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "footView")
|
if footView == nil{
|
footView = UITableViewHeaderFooterView(reuseIdentifier: "footView")
|
}
|
footView?.contentView.backgroundColor = .white
|
return footView
|
}
|
|
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
|
return 30
|
}
|
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
|
//74116 [拼车]缺少司机未出发状态更新及正在为您寻找拼友字段(该字段在未有拼友的情况下会一直显示)
|
// if viewModel.dataSource.value?.spellSuccess == 1{
|
// return 0
|
// }
|
return 30
|
}
|
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
let item = carpoolingItems[indexPath.row]
|
let cell = tableView.dequeueReusableCell(withIdentifier: "_YYSpecialCarpoolingCarTCell") as! YYSpecialCarpoolingCarTCell
|
|
/// 订单状态(2=待出发,3=待到达预约地点,4=待乘客上车,5=服务中,6=完成服务,7=待支付,8=待评价,9=已完成,10=已取消,11=改派中)
|
var diff = ""
|
var user = ""
|
if item.userId == readUser().id{
|
user = "你"
|
}else{
|
user = "尾号\(item.phone.substring(from: 7))"
|
}
|
|
cell.currentPointImg.image = UIImage(named: "icon_unselect")
|
|
//2: 准备(接送),3,4:正在(接送)5:已上车(接),送, 6:送达,7:待支付,8-9完成
|
|
|
|
//接
|
if indexPath.row < carpoolingItems.count / 2 {
|
cell.subTitleL.text = item.startAddress
|
|
if item.orderState.rawValue == 2 || item.orderState.rawValue == 1 || item.orderState.rawValue == 8 || item.orderState.rawValue == 3 || item.orderState.rawValue == 7{
|
diff = "接\(user)"
|
cell.datetimeL.text = ""
|
// cell.titleL.textColor = UIColor(hexString: "#333333")
|
}
|
|
if item.orderState.rawValue == 3 || item.orderState.rawValue == 4{ //正在接
|
diff = "司机正在接\(user)"
|
// cell.currentPointImg.image = UIImage(named: "icon_select")
|
cell.datetimeL.text = ""
|
// cell.titleL.textColor = UIColor(hexString: "#00BF30")
|
hintL.text = diff
|
}
|
|
if item.orderState.rawValue == 5{
|
diff = "\(user)已上车"
|
cell.datetimeL.text = item.travelTime_
|
cell.titleL.textColor = UIColor(hexString: "#00BF30")
|
}
|
|
}else{
|
cell.subTitleL.text = item.endAddress
|
if item.orderState.rawValue == 3 || item.orderState.rawValue == 2 || item.orderState.rawValue == 1 || item.orderState.rawValue == 8 || item.orderState.rawValue == 4{
|
diff = "送\(user)"
|
cell.datetimeL.text = ""
|
cell.titleL.textColor = UIColor(hexString: "#333333")
|
}
|
|
if item.orderState.rawValue == 5{
|
diff = "司机送\(user)"
|
cell.datetimeL.text = ""
|
// cell.currentPointImg.image = UIImage(named: "icon_select")
|
// cell.titleL.textColor = UIColor(hexString: "#00BF30")
|
|
if user == "你"{
|
if let m = viewModel.driverInfo.value{
|
|
let font = UIFont.systemFont(ofSize: 12, weight: .medium)
|
let color = UIColor(hexString: "#00BF30")!
|
let color1 = UIColor(hexString: "#FC7B43")!
|
var attribute = AttributedStringbuilder.build()
|
attribute = attribute.add(string: " 已为您服务", withFont: font, withColor: color)
|
attribute = attribute.add(string: "\(m.servedTime)", withFont: font, withColor: color1)
|
attribute = attribute.add(string: "分钟,累计行驶", withFont: font, withColor: color)
|
attribute = attribute.add(string: String(format: "%.2lf", m.servedMileage), withFont: font, withColor: color1)
|
attribute = attribute.add(string: "公里\n距离目的地还有", withFont: font, withColor: color)
|
attribute = attribute.add(string: "\(m.reservationMileage)", withFont: font, withColor: color1)
|
attribute = attribute.add(string: "公里,预计行驶", withFont: font, withColor: color)
|
attribute = attribute.add(string: "\(m.laveTime)", withFont: font, withColor: color1)
|
attribute = attribute.add(string: "分钟 ", withFont: font, withColor: color)
|
hintL.attributedText = attribute.mutableAttributedString
|
}
|
|
}else{
|
hintL.text = diff
|
}
|
}
|
|
if item.orderState.rawValue > 5{
|
diff = "\(user)已送达"
|
cell.datetimeL.text = item.travelTime_
|
cell.titleL.textColor = UIColor(hexString: "#FC7B43")
|
}
|
}
|
|
if indexPath.row == currentIndex - 1{
|
cell.currentPointImg.image = UIImage(named: "icon_select")
|
cell.titleL.textColor = UIColor(hexString: "#00BF30")
|
}
|
|
cell.titleL.text = diff
|
return cell
|
}
|
|
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
return 60
|
}
|
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
return carpoolingItems.count
|
}
|
}
|
|
|
class TableHeaderView:UITableViewHeaderFooterView{
|
|
private var titleL:UILabel!
|
private var progressImg = UIImageView(image: UIImage(named: "icon_progress"))
|
private var searchL:UILabel!
|
private let rotationAnim = CABasicAnimation(keyPath: "transform.rotation.z")
|
|
override init(reuseIdentifier: String?) {
|
super.init(reuseIdentifier: reuseIdentifier)
|
|
titleL = UILabel()
|
titleL.textColor = UIColor(hexString: "#FC7B43")
|
titleL.font = UIFont.systemFont(ofSize: 14, weight: .medium)
|
contentView.backgroundColor = .white
|
|
contentView.addSubview(titleL)
|
titleL.snp.makeConstraints { make in
|
make.left.equalTo(14)
|
make.height.equalTo(20)
|
make.centerY.equalToSuperview()
|
}
|
|
searchL = UILabel()
|
searchL.isHidden = true
|
searchL.text = "正在为您寻找拼友"
|
searchL.font = UIFont.systemFont(ofSize: 14, weight: .medium)
|
searchL.textColor = UIColor(hexString: "#FC7B43")
|
contentView.addSubview(searchL)
|
searchL.snp.makeConstraints { make in
|
make.center.equalToSuperview()
|
}
|
|
contentView.addSubview(progressImg)
|
progressImg.isHidden = true
|
progressImg.snp.makeConstraints { make in
|
make.centerY.equalTo(searchL)
|
make.right.equalTo(searchL.snp.left).offset(-9)
|
}
|
startRotationAni()
|
}
|
|
required init?(coder: NSCoder) {
|
super.init(coder: coder)
|
}
|
|
func setTitle(_ text:String){
|
titleL.text = text
|
}
|
|
func startRotationAni(){
|
|
if let ani = progressImg.layer.animationKeys(),ani.contains("roll") == true{
|
return
|
}
|
|
titleL.isHidden = true
|
searchL.isHidden = false
|
progressImg.isHidden = false
|
|
rotationAnim.fromValue = 0
|
rotationAnim.toValue = Double.pi * 2
|
rotationAnim.repeatCount = MAXFLOAT
|
rotationAnim.duration = 2
|
rotationAnim.isRemovedOnCompletion = false
|
progressImg.layer.add(rotationAnim, forKey: "roll")
|
|
progressImg.layer.animationKeys()
|
}
|
|
func stopRotationAni(){
|
titleL.isHidden = false
|
searchL.isHidden = true
|
progressImg.isHidden = true
|
progressImg.layer.removeAllAnimations()
|
}
|
}
|
|
class CustomTableView:UITableView{
|
|
override init(frame: CGRect, style: UITableView.Style) {
|
super.init(frame: frame, style: style)
|
}
|
|
required init?(coder: NSCoder) {
|
fatalError("init(coder:) has not been implemented")
|
}
|
|
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
let alpha = alphaOfPoint(point: point)
|
// 处于当前view及sub view的点击位置颜色的alpha值大于阈值,则事件不穿透,否则就透传
|
if alpha >= 0.5{
|
return true
|
}
|
return false
|
}
|
|
func alphaOfPoint(point: CGPoint) -> CGFloat {
|
return alphaOfPointFromLayer(point: point)
|
}
|
|
|
func alphaOfPointFromLayer(point: CGPoint) -> CGFloat {
|
var pixel = [UInt8](repeatElement(0, count: 4))
|
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
|
context?.setBlendMode(.copy)
|
context?.translateBy(x: -point.x, y: -point.y)
|
if let context = context {
|
layer.render(in: context)
|
}
|
let alpha = CGFloat(pixel[3]) / CGFloat(255.0)
|
|
return alpha
|
}
|
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
if self.point(inside: point, with: event) {
|
return super.hitTest(point, with: event)
|
}
|
guard isUserInteractionEnabled, !isHidden, alpha > 0 else {
|
return nil
|
}
|
|
for subview in subviews.reversed() {
|
let convertedPoint = subview.convert(point, from: self)
|
if let hitView = subview.hitTest(convertedPoint, with: event) {
|
return hitView
|
}
|
}
|
return nil
|
}
|
}
|