1836 lines
83 KiB
Swift
1836 lines
83 KiB
Swift
//
|
||
// VehicleMonitoringController.swift
|
||
// OrderScheduling
|
||
//
|
||
// Created by 中道 on 2023/8/14.
|
||
//
|
||
|
||
import Foundation
|
||
import DDControlsKit_Private
|
||
import DDMAMapKit_Private
|
||
import DDAutoUIKit_Private
|
||
import RxSwift
|
||
import RxCocoa
|
||
import RxRelay
|
||
import JXCategoryView
|
||
import SnapKit
|
||
import DDUIGestureRecognizer
|
||
import DDUtilsSwiftKit_Private
|
||
|
||
fileprivate let vehicleMonitoringPannelViewHeight = auto(300)
|
||
fileprivate let vehicleMonitoringPannelCategoryViewHeight = auto(40)
|
||
fileprivate let vehicleMonitoringListDetailViewHeight = auto(270)
|
||
|
||
fileprivate let vehicleMonitoringPointAnnotationW = auto(120)
|
||
fileprivate let vehicleMonitoringPointAnnotationNameLeftInset = auto(35)
|
||
fileprivate let vehicleMonitoringPointAnnotationNameRightInset = auto(35)
|
||
fileprivate let vehicleMonitoringPointAnnotationNameAtLeastH = auto(30)
|
||
|
||
extension VehicleMonitoringController {
|
||
func addAction() {
|
||
MCOUNT.messageCountRelay
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] count in
|
||
if count > 0 {
|
||
self?.messageView.countLabel.isHidden = false
|
||
self?.messageView.countLabel.text = String(count)
|
||
self?.messageView.countLabel.snp.updateConstraints({ make in
|
||
make.width.equalTo(20)
|
||
})
|
||
}else{
|
||
self?.messageView.countLabel.isHidden = true
|
||
self?.messageView.countLabel.snp.updateConstraints({ make in
|
||
make.width.equalTo(0)
|
||
})
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
reloadRelay
|
||
.observe(on: MainScheduler.instance)
|
||
.do(onNext: {[weak self] _ in
|
||
self?.view.dd_showHUD()
|
||
})
|
||
.flatMapLatest {[weak self] _ in
|
||
guard let self = self else {
|
||
return Single.just((
|
||
nil as ResponseModel<VehicleMonitorListDataModel>?,
|
||
nil as ResponseModel<GeneralInfoDataModel>?,
|
||
[] as [AlarmListDataModel]
|
||
))
|
||
}
|
||
return Single.zip(RQ.vehicleMonitorList(),RQ.generalInfo(),self.getAllAlarmList(pageNum: 1, alarmList: []))
|
||
}
|
||
.observe(on: MainScheduler.instance)
|
||
.do(onNext: {[weak self] _,_,_ in
|
||
self?.view.dd_hideHUD()
|
||
})
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] response,generalInfo,alarmList in
|
||
if generalInfo?.success == true {
|
||
/// 如果list列表数量为0的话就显示当前位置
|
||
if let lat = generalInfo?.data?.addressLat,let lon = generalInfo?.data?.addressLon {
|
||
self?.defaultCoordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
|
||
}else{
|
||
self?.defaultCoordinate = nil
|
||
}
|
||
}else{
|
||
self?.defaultCoordinate = nil
|
||
self?.view.dd_makeToast(response?.msg)
|
||
}
|
||
|
||
if response?.success == true {
|
||
self?.dataModel = response?.data
|
||
let rosterTitle = "排班"
|
||
let rosterCount = NSNumber(value: response?.data?.vehicleMonitorCount.rosterCount ?? 0)
|
||
let onLineTitle = "上线"
|
||
let onLineCount = NSNumber(value: response?.data?.vehicleMonitorCount.onLineCount ?? 0)
|
||
let lostConnectionTitle = "掉线"
|
||
let lostConnectionCount = NSNumber(value: response?.data?.vehicleMonitorCount.lostConnectionCount ?? 0)
|
||
let leisureTitle = "空闲"
|
||
let leisureCount = NSNumber(value: response?.data?.vehicleMonitorCount.leisureCount ?? 0)
|
||
let busyTitle = "忙碌"
|
||
let busyCount = NSNumber(value: response?.data?.vehicleMonitorCount.busyCount ?? 0)
|
||
// let alarmCount = String(response?.data?.vehicleMonitorCount.alarmCount ?? 0)+"\n"+"报警"
|
||
if USER.supplierType == 1 {
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.titles = [rosterTitle,onLineTitle,lostConnectionTitle,leisureTitle,busyTitle]
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.counts = [rosterCount,onLineCount,lostConnectionCount,leisureCount,busyCount]
|
||
}else{
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.titles = [onLineTitle,lostConnectionTitle,leisureTitle,busyTitle]
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.counts = [onLineCount,lostConnectionCount,leisureCount,busyCount]
|
||
}
|
||
|
||
/// 选中信息也要置空
|
||
self?.resetSelectedOfData()
|
||
|
||
/// 刷新列表数据
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.reloadDataWithoutListContainer()
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.listContainer.reloadData()
|
||
self?.categoryView(self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView, didSelectedItemAt: self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.selectedIndex ?? 0)
|
||
}else{
|
||
self?.view.dd_makeToast(response?.msg)
|
||
self?.dataModel = nil
|
||
self?.mapModel = nil
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.titles = []
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.counts = []
|
||
self?.vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.reloadData()
|
||
}
|
||
|
||
if alarmList.count > 0 {
|
||
self?.alarmList = alarmList
|
||
|
||
var items : [String] = []
|
||
for i in 0..<alarmList.count {
|
||
let item = alarmList[i]
|
||
items.append((item.alarmTypeString ?? "")+":"+(item.vehicleName ?? ""))
|
||
}
|
||
self?.vehicleMonitoringView.offlineView.offLineLabel.items = items
|
||
self?.vehicleMonitoringView.alarmView.count.text = String(items.count)
|
||
self?.vehicleMonitoringView.offlineView.isHidden = false
|
||
self?.vehicleMonitoringView.alarmView.isHidden = false
|
||
}else{
|
||
self?.vehicleMonitoringView.offlineView.isHidden = true
|
||
self?.vehicleMonitoringView.alarmView.isHidden = true
|
||
}
|
||
|
||
/// 从详情页返回
|
||
self?.vehicleMonitoringListDetailView.backButton.sendActions(for: .touchUpInside)
|
||
|
||
/// 重置地图锚点
|
||
self?.modifyMapAnchor()
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
messageTapGes.rx.event
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
MESSAGETOOL.openMessageCenter(by: self?.navigationController)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
refreshButton.rx.tap
|
||
.subscribe(onNext: {[weak self] _ in
|
||
self?.preRefreshRelay.accept(nil)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleLogoutView.cancelButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: { _ in
|
||
ENTRY.dismiss(name: vehicleLogoutEntry)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleLogoutView.sureButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
ENTRY.dismiss(name: vehicleLogoutEntry) {[weak self] in
|
||
self?.vehicleLogoutRelay.accept(self?.vehicleLogoutModel)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
showVehicleEntryRelay
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] model in
|
||
if let vehicleName = model?.vehicleName,let driverName = model?.driverName {
|
||
self?.vehicleLogoutView.titleLabel.text = vehicleName+"/"+driverName
|
||
self?.vehicleLogoutView.contentLabel.text = "该车辆确定要退出登录吗?"
|
||
self?.vehicleLogoutModel = model
|
||
}
|
||
if let view = self?.vehicleLogoutView {
|
||
ENTRY.showVehicleLogoutEntry(view: view,name: vehicleLogoutEntry)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleLogoutRelay
|
||
.filter({ model in
|
||
return model?.vehicleId != nil
|
||
})
|
||
.observe(on: MainScheduler.instance)
|
||
.do(onNext: {[weak self] _ in
|
||
self?.view.dd_showHUD()
|
||
})
|
||
.flatMapLatest { model in
|
||
return RQ.vehicleLogout(parameters: VehicleLogoutParameters(vehicleId: model!.vehicleId!))
|
||
}
|
||
.observe(on: MainScheduler.instance)
|
||
.do(onNext: {[weak self] _ in
|
||
self?.view.dd_hideHUD()
|
||
})
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] response in
|
||
if response?.success == true {
|
||
self?.reloadRelay.accept(nil)
|
||
}else{
|
||
self?.view.dd_makeToast(response?.msg)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringListDetailView.callButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
if let model = self?.selectedModel {
|
||
URLLINKS.openUrl(type: .phone, appending: model.driverPhone)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringListDetailView.backButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
self?.hideListDetail()
|
||
self?.hideIncidentLocation()
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringListDetailView.settingButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
if let view = self?.vehicleConfigView {
|
||
view.showMonitoring(false)
|
||
ENTRY.showVehicleMonitoringConfigEntry(view: view, name: vehicleMonitoringConfigEntry)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringListDetailView.showIncidentLocationHandler = {[weak self] incidentCoordi,destCoordi in
|
||
/// 先隐藏
|
||
self?.hideIncidentLocation()
|
||
|
||
let incidentCoordiAnnotation = MAPointAnnotation()
|
||
incidentCoordiAnnotation.dd_image = UIImage(named: "vehichleMonitoring_start_32")
|
||
incidentCoordiAnnotation.coordinate = incidentCoordi
|
||
incidentCoordiAnnotation.annotationClass = VehicleMonitoringIncidentLocationAnnotationView.self
|
||
incidentCoordiAnnotation.tag = -1
|
||
self?.vehicleMonitoringView.maMapView.maMapView.addAnnotation(incidentCoordiAnnotation)
|
||
if let destCoordi {
|
||
let destCoordiAnnotation = MAPointAnnotation()
|
||
destCoordiAnnotation.dd_image = UIImage(named: "vehichleMonitoring_terminal_32")
|
||
destCoordiAnnotation.coordinate = destCoordi
|
||
destCoordiAnnotation.annotationClass = VehicleMonitoringIncidentLocationAnnotationView.self
|
||
destCoordiAnnotation.tag = -2
|
||
self?.vehicleMonitoringView.maMapView.maMapView.addAnnotation(destCoordiAnnotation)
|
||
}
|
||
}
|
||
|
||
vehicleMonitoringListDetailView.showOrderDetailHandler = { taskModel in
|
||
WEBTOOL.open(name: .workOrderDetail, appending: "&queryType=\(OrderTypeEnum.TO_RESCUE.rawValue)&userOrderId=\(taskModel.userOrderId)&orderCode=\(taskModel.orderCode)&taskOrderId=\(taskModel.taskOrderId)")
|
||
}
|
||
|
||
vehicleConfigView.cancelGes.rx.event
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: { _ in
|
||
ENTRY.dismiss(name: vehicleMonitoringConfigEntry)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringListDetailView.videoButton.rx.tap
|
||
.observe(on: ConcurrentMainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
self?.navigationController?.pushViewController(VehicleMonitorVideoController(vehicleId: self?.selectedModel?.vehicleId,simNumber: self?.selectedModel?.number), animated: true)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
vehicleMonitoringView.alarmView.dd_addTapGesture {
|
||
WEBTOOL.open(name: .vehicleAlarmList, appending: nil)
|
||
}
|
||
|
||
vehicleMonitoringView.offlineView.offLineLabel.onTap = {[weak self] index in
|
||
let model = self?.alarmList[index]
|
||
if let code = model?.code {
|
||
WEBTOOL.open(name: .vehicleAlarmDetail, appending: "&code=\(code)")
|
||
}
|
||
}
|
||
|
||
vehicleConfigView.logoutGes.rx.event
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
ENTRY.dismiss(name: vehicleMonitoringConfigEntry) {[weak self] in
|
||
self?.showVehicleEntryRelay.accept(self?.selectedModel)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
// 点击tabBar 需要刷下下列
|
||
preRefreshRelay
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
NewTraining.default.newTrainingRelay.accept(nil)
|
||
MCOUNT.newestMessage()
|
||
self?.reloadRelay.accept(nil)
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
}
|
||
|
||
func getAllAlarmList(pageNum: Int,alarmList: [AlarmListDataModel]) -> Single<[AlarmListDataModel]> {
|
||
func recursive(pageNum: Int,alarmList: [AlarmListDataModel]) -> Single<[AlarmListDataModel]> {
|
||
return RQ.alarmList(parameters: AlarmListParameters(pageNum: pageNum, supplierId: USER.supplierId,handStatus: AlarmListParameters.HandStatusEnum.pending.rawValue))
|
||
.flatMap { response in
|
||
if (response?.data?.count ?? 0) == 0 {
|
||
return Single.create { single in
|
||
single(.success(alarmList))
|
||
return Disposables.create()
|
||
}
|
||
}
|
||
let addAlarmList = alarmList + (response?.data ?? [])
|
||
return recursive(pageNum: pageNum + 1, alarmList: addAlarmList)
|
||
}
|
||
}
|
||
|
||
return recursive(pageNum: 1, alarmList: [])
|
||
}
|
||
}
|
||
|
||
extension VehicleMonitoringController : DDMAMapViewDelegate {
|
||
public func dd_mapView(_ mapView: MAMapView, viewFor annotation: MAAnnotation) -> MAAnnotationView {
|
||
if annotation.isMember(of: MAPointAnnotation.self) {
|
||
let pointAnnotation = annotation as! MAPointAnnotation
|
||
if pointAnnotation.annotationClass == VehicleMonitoringPointAnnotation.self{
|
||
let DriverPointReuseIndentifier = "DispatchMapStatePointAnnotation"
|
||
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: DriverPointReuseIndentifier) as? VehicleMonitoringPointAnnotation
|
||
if annotationView == nil {
|
||
annotationView = VehicleMonitoringPointAnnotation.init(annotation: pointAnnotation, reuseIdentifier: DriverPointReuseIndentifier)
|
||
}
|
||
|
||
let model = mapModel?[pointAnnotation.tag]
|
||
/// 绑定车辆id到annotation
|
||
pointAnnotation.vehicleId = model?.vehicleId
|
||
annotationView!.annotation = pointAnnotation
|
||
annotationView?.zIndex = model?.zIndex ?? 0
|
||
|
||
if let annotationView, let model, let shouldShowSmallAnnotation {
|
||
annotationViewStateConfig(annotationView: annotationView, vehicleModel: model, shouldShowSmallAnnotation: shouldShowSmallAnnotation)
|
||
}
|
||
|
||
let labelSize = annotationView?.titleLabel.sizeThatFits(CGSize(width: auto(100), height: .infinity)) ?? .zero
|
||
let annotationViewW = labelSize.width
|
||
let annotationViewH = auto(50) + labelSize.height
|
||
annotationView?.frame = CGRect(origin: (annotationView?.frame.origin)!, size: CGSize(width: annotationViewW, height: annotationViewH))
|
||
return annotationView!
|
||
}
|
||
|
||
if pointAnnotation.annotationClass == DispatchMapSericeAddressPointAnnotation.self{
|
||
let DriverPointReuseIndentifier = "DispatchMapSericeAddressPointAnnotation"
|
||
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: DriverPointReuseIndentifier) as? DispatchMapSericeAddressPointAnnotation
|
||
if annotationView == nil {
|
||
annotationView = DispatchMapSericeAddressPointAnnotation.init(annotation: pointAnnotation, reuseIdentifier: DriverPointReuseIndentifier)
|
||
}
|
||
annotationView!.annotation = pointAnnotation
|
||
return annotationView!
|
||
}
|
||
|
||
if pointAnnotation.annotationClass == VehicleMonitoringIncidentLocationAnnotationView.self {
|
||
let incidentPointReuseIndentifier = "VehicleMonitoringIncidentLocationAnnotationView"
|
||
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: incidentPointReuseIndentifier) as? VehicleMonitoringIncidentLocationAnnotationView
|
||
if annotationView == nil {
|
||
annotationView = VehicleMonitoringIncidentLocationAnnotationView.init(annotation: pointAnnotation, reuseIdentifier: incidentPointReuseIndentifier)
|
||
}
|
||
annotationView!.annotation = pointAnnotation
|
||
annotationView!.image = pointAnnotation.dd_image
|
||
annotationView!.zIndex = Int.max
|
||
return annotationView!
|
||
}
|
||
}
|
||
|
||
return MAAnnotationView.init(annotation: annotation, reuseIdentifier: "cell")
|
||
}
|
||
|
||
public func dd_mapView(_ mapView: MAMapView, didAnnotationViewTapped view: MAAnnotationView) {
|
||
if view.isKind(of: VehicleMonitoringPointAnnotation.self) != true {
|
||
return
|
||
}
|
||
|
||
zIndex += 1
|
||
view.zIndex = zIndex
|
||
|
||
if let tapPointAnnotation = view.annotation as? MAPointAnnotation, let mapModel = self.mapModel {
|
||
let model = mapModel[tapPointAnnotation.tag]
|
||
selectVehicle(selectState: true,vehicleModel: model, currentTableViewVehicleModels: mapModel, selectIndex: tapPointAnnotation.tag, mapView: mapView)
|
||
|
||
if model.vehicleId == selectedModel?.vehicleId {
|
||
if isListDetailShowed == false {
|
||
showListDetail(vehicleModel: model)
|
||
}else{
|
||
hideListDetail()
|
||
}
|
||
}else{
|
||
showListDetail(vehicleModel: model)
|
||
}
|
||
}
|
||
}
|
||
|
||
public func dd_mapView(_ mapView: MAMapView, mapDidZoomByUser wasUserAction: Bool) {
|
||
// //// 缩小过一次后就不需要频繁调用移除添加
|
||
// if mapView.zoomLevel <= 14 {
|
||
// shouldShowSmallAnnotation = true
|
||
//
|
||
// if isShowSmallAnnotation == false {
|
||
// let annotations = mapView.annotations
|
||
// mapView.removeAnnotations(annotations)
|
||
// mapView.addAnnotations(annotations)
|
||
//
|
||
// isShowSmallAnnotation = true
|
||
// }
|
||
// }else{
|
||
shouldShowSmallAnnotation = false
|
||
|
||
if isShowSmallAnnotation == true {
|
||
let annotations = mapView.annotations
|
||
mapView.removeAnnotations(annotations)
|
||
mapView.addAnnotations(annotations)
|
||
isShowSmallAnnotation = false
|
||
}
|
||
// }
|
||
|
||
}
|
||
}
|
||
|
||
// MARK: JXCategoryListContainerViewDelegate
|
||
extension VehicleMonitoringController : JXCategoryListContainerViewDelegate {
|
||
public func number(ofListsInlistContainerView listContainerView: JXCategoryListContainerView!) -> Int {
|
||
return vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.titles.count
|
||
}
|
||
|
||
public func listContainerView(_ listContainerView: JXCategoryListContainerView!, initListFor index: Int) -> JXCategoryListContentViewDelegate! {
|
||
var vc : VehicleMonitoringListController?
|
||
|
||
if USER.supplierType == 1 {
|
||
if index == 0 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.rosterList,isPaiban: true)
|
||
}else if index == 1 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.onLineList)
|
||
}else if index == 2 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.lostConnectionList)
|
||
}else if index == 3 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.leisureList)
|
||
}else if index == 4 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.busyList)
|
||
}else if index == 5 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.alarmList,isAlarm: true)
|
||
}
|
||
}else{
|
||
if index == 0 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.onLineList)
|
||
}else if index == 1 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.lostConnectionList)
|
||
}else if index == 2 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.leisureList)
|
||
}else if index == 3 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.busyList)
|
||
}else if index == 4 {
|
||
vc = VehicleMonitoringListController(models: dataModel?.alarmList,isAlarm: true)
|
||
}
|
||
}
|
||
|
||
vc?.selectCellBlock = {[weak self] (model,item) in
|
||
if let models = vc?.models,let mapView = self?.vehicleMonitoringView.maMapView.maMapView {
|
||
self?.selectVehicle(selectState: true,vehicleModel: model, currentTableViewVehicleModels: models, selectIndex: item, mapView: mapView)
|
||
|
||
self?.showMapCenter(with: model)
|
||
}
|
||
}
|
||
vc?.showDetailBlock = {[weak self] (model,item) in
|
||
if let models = vc?.models,let mapView = self?.vehicleMonitoringView.maMapView.maMapView {
|
||
self?.selectVehicle(selectState: true,vehicleModel: model, currentTableViewVehicleModels: models, selectIndex: item, mapView: mapView)
|
||
|
||
self?.showListDetail(vehicleModel: model)
|
||
|
||
self?.showMapCenter(with: model)
|
||
}
|
||
}
|
||
|
||
vc?.showMaxBlock = {[weak self] in
|
||
if self?.pannelPanGes.panGesValue.expandLevel != .max {
|
||
self?.pannelPanGes.expand(.max)
|
||
}
|
||
}
|
||
|
||
return vc
|
||
}
|
||
}
|
||
|
||
extension VehicleMonitoringController : JXCategoryViewDelegate {
|
||
public func categoryView(_ categoryView: JXCategoryBaseView!, didSelectedItemAt index: Int) {
|
||
DispatchQueue.main.async {[weak self] in
|
||
self?.reloadData(index: index)
|
||
|
||
if let containerView = categoryView.listContainer as? JXCategoryListContainerView {
|
||
let key = NSNumber(value: index)
|
||
let vc = containerView.validListDict[key]
|
||
self?.currentTableView = (vc as? VehicleMonitoringListController)?.vehicleMonitoringListView.tableView
|
||
}
|
||
}
|
||
}
|
||
|
||
func reloadData(index:Int) {
|
||
/// 移除所有的annottaion
|
||
if let annotations = vehicleMonitoringView.maMapView.maMapView.annotations {
|
||
vehicleMonitoringView.maMapView.maMapView.removeAnnotations(annotations)
|
||
}
|
||
|
||
/// 添加新的mapModel
|
||
if USER.supplierType == 1 {
|
||
if index == 0 {
|
||
mapModel = dataModel?.rosterList
|
||
}else if index == 1 {
|
||
mapModel = dataModel?.onLineList
|
||
}else if index == 2 {
|
||
mapModel = dataModel?.lostConnectionList
|
||
}else if index == 3 {
|
||
mapModel = dataModel?.leisureList
|
||
}else if index == 4 {
|
||
mapModel = dataModel?.busyList
|
||
}else if index == 5 {
|
||
mapModel = dataModel?.alarmList
|
||
}
|
||
}else{
|
||
if index == 0 {
|
||
mapModel = dataModel?.onLineList
|
||
}else if index == 1 {
|
||
mapModel = dataModel?.lostConnectionList
|
||
}else if index == 2 {
|
||
mapModel = dataModel?.leisureList
|
||
}else if index == 3 {
|
||
mapModel = dataModel?.busyList
|
||
}else if index == 4 {
|
||
mapModel = dataModel?.alarmList
|
||
}
|
||
}
|
||
|
||
for index in 0..<(mapModel?.count ?? 0) {
|
||
let model = mapModel?[index]
|
||
if model?.lat != nil && model?.lon != nil {
|
||
let coordinate = CLLocationCoordinate2D(latitude: Double(model?.lat ?? "") ?? 0, longitude: Double(model?.lon ?? "") ?? 0)
|
||
let pointAnnotation = MAPointAnnotation.init()
|
||
pointAnnotation.annotationClass = VehicleMonitoringPointAnnotation.self
|
||
pointAnnotation.coordinate = coordinate
|
||
pointAnnotation.tag = index
|
||
vehicleMonitoringView.maMapView.maMapView.addAnnotation(pointAnnotation)
|
||
}
|
||
}
|
||
|
||
if let annotations = vehicleMonitoringView.maMapView.maMapView.annotations, annotations.isEmpty == false {
|
||
vehicleMonitoringView.maMapView.maMapView.showAnnotations(annotations, animated: true)
|
||
modifyMapAnchor()
|
||
}else{
|
||
let coordinate = defaultCoordinate ?? vehicleMonitoringView.maMapView.maMapView.userLocation.coordinate
|
||
vehicleMonitoringView.maMapView.maMapView.setCenter(coordinate, animated: true)
|
||
vehicleMonitoringView.maMapView.maMapView.zoomLevel = 18
|
||
}
|
||
}
|
||
}
|
||
|
||
extension VehicleMonitoringController {
|
||
func selectVehicle(selectState: Bool,vehicleModel: VehicleMonitorListDataModel.ItemModel, currentTableViewVehicleModels: [VehicleMonitorListDataModel.ItemModel],selectIndex: Int, mapView: MAMapView) {
|
||
|
||
resetSelectedOfDataModel()
|
||
|
||
/// 在当前mapModel中查找vehicleId,如果找到的话就先删除再添加
|
||
if let selectedModel = currentTableViewVehicleModels.first(where: {[weak self] model in
|
||
return model.vehicleId == self?.selectedVehicleId
|
||
}), let selectedTableView = self.selectedTableView,let currentTableView = self.currentTableView, selectedTableView == currentTableView {
|
||
if let tag = currentTableViewVehicleModels.firstIndex(where: { model in
|
||
return selectedModel.vehicleId == model.vehicleId
|
||
}) {
|
||
if let annotation = mapView.annotations.first(where: { annotation in
|
||
let pointAnnotation = annotation as? MAPointAnnotation
|
||
return pointAnnotation?.vehicleId == selectedModel.vehicleId
|
||
}) {
|
||
mapView.removeAnnotation(annotation as? MAAnnotation)
|
||
|
||
selectedModel.isSelected = false
|
||
let coordinate = CLLocationCoordinate2D(latitude: Double(selectedModel.lat ?? "0") ?? 0, longitude: Double(selectedModel.lon ?? "0") ?? 0)
|
||
let pointAnnotation = MAPointAnnotation.init()
|
||
pointAnnotation.annotationClass = VehicleMonitoringPointAnnotation.self
|
||
pointAnnotation.coordinate = coordinate
|
||
pointAnnotation.tag = tag
|
||
mapView.addAnnotation(pointAnnotation)
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 找到当前的车辆
|
||
/// 移除之前的annotation
|
||
if let oldAnnotation = mapView.annotations.first(where: { annotation in
|
||
let pointAnnotation = annotation as? MAPointAnnotation
|
||
return pointAnnotation?.tag == selectIndex
|
||
}) {
|
||
mapView.removeAnnotation(oldAnnotation as? MAAnnotation)
|
||
}
|
||
|
||
/// 将当前选中设为true
|
||
vehicleModel.isSelected = selectState
|
||
zIndex+=1
|
||
vehicleModel.zIndex = zIndex
|
||
|
||
/// 重新添加新的annotation
|
||
let coordinate = CLLocationCoordinate2D(latitude: Double(vehicleModel.lat ?? "0") ?? 0, longitude: Double(vehicleModel.lon ?? "0") ?? 0)
|
||
let pointAnnotation = MAPointAnnotation.init()
|
||
pointAnnotation.annotationClass = VehicleMonitoringPointAnnotation.self
|
||
pointAnnotation.coordinate = coordinate
|
||
pointAnnotation.tag = selectIndex
|
||
mapView.addAnnotation(pointAnnotation)
|
||
|
||
/// 记录当前的选中车辆id
|
||
selectedVehicleId = vehicleModel.vehicleId
|
||
|
||
/// 刷新tableview,记录当前的tableview
|
||
selectedTableView?.reloadData()
|
||
currentTableView?.reloadData()
|
||
selectedTableView = currentTableView
|
||
}
|
||
|
||
func resetSelectedOfDataModel() {
|
||
// 去掉其他tableview的选中
|
||
for index in 0..<(dataModel?.rosterList.count ?? 0) {
|
||
let _model = dataModel?.rosterList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
for index in 0..<(dataModel?.onLineList.count ?? 0) {
|
||
let _model = dataModel?.onLineList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
for index in 0..<(dataModel?.lostConnectionList.count ?? 0) {
|
||
let _model = dataModel?.lostConnectionList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
for index in 0..<(dataModel?.leisureList.count ?? 0) {
|
||
let _model = dataModel?.leisureList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
for index in 0..<(dataModel?.busyList.count ?? 0) {
|
||
let _model = dataModel?.busyList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
for index in 0..<(dataModel?.alarmList.count ?? 0) {
|
||
let _model = dataModel?.alarmList[index]
|
||
_model?.isSelected = false
|
||
}
|
||
}
|
||
|
||
func annotationViewStateConfig(annotationView: VehicleMonitoringPointAnnotation,vehicleModel: VehicleMonitorListDataModel.ItemModel, shouldShowSmallAnnotation: Bool) {
|
||
var backgroundColor : UIColor?
|
||
var bigImage : UIImage?
|
||
var middleImage : UIImage?
|
||
|
||
if let _ = vehicleModel.alarmType {
|
||
|
||
}else{
|
||
switch vehicleModel.vehicleStatus?.code {
|
||
case VehicleStatusCodeEnum.offLine.rawValue,VehicleStatusCodeEnum.lostConnection.rawValue:
|
||
backgroundColor = .hex("858585")
|
||
bigImage = UIImage(named: "vehicleMonitoring_offline_big")
|
||
middleImage = UIImage(named: "vehicleMonitor_offline_cell_flag_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.onLine.rawValue,VehicleStatusCodeEnum.leisure.rawValue:
|
||
backgroundColor = .hex("067BB9")
|
||
bigImage = UIImage(named: "vehicleMonitoring_empty_big")
|
||
middleImage = UIImage(named: "vehicleMonitor_empty_cell_flag_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.busy.rawValue:
|
||
backgroundColor = .hex("F05412")
|
||
bigImage = UIImage(named: "vehicleMonitoring_busy_big")
|
||
middleImage = UIImage(named: "vehicleMonitor_busy_cell_onlne_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.BuyBusy.rawValue:
|
||
backgroundColor = .hex("F05412")
|
||
bigImage = UIImage(named: "vehicleMonitoring_busy_big")
|
||
middleImage = UIImage(named: "vehicleMonitor_busy_cell_onlne_bg")
|
||
break
|
||
default:
|
||
backgroundColor = .hex("858585")
|
||
bigImage = UIImage(named: "vehicleMonitoring_offline_big")
|
||
middleImage = UIImage(named: "vehicleMonitor_offline_cell_flag_bg")
|
||
break
|
||
}
|
||
|
||
switch vehicleModel.onlineStatus?.code {
|
||
case OnlineStatusModel.OnlineStatusCodeEnum.onLine.rawValue:
|
||
annotationView.bigStateLabel.textColor = .white
|
||
annotationView.middleStateLabel.textColor = .white
|
||
break
|
||
default:
|
||
annotationView.bigStateLabel.textColor = .hex("CCCCCC")
|
||
annotationView.middleStateLabel.textColor = .hex("CCCCCC")
|
||
break
|
||
}
|
||
}
|
||
if vehicleModel.isSelected == true {
|
||
annotationView.bigImageView.isHidden = false
|
||
annotationView.bigStateLabel.isHidden = false
|
||
annotationView.smallImageView.isHidden = true
|
||
annotationView.middleImageView.isHidden = true
|
||
annotationView.bigImageView.image = bigImage
|
||
annotationView.bigStateLabel.text = vehicleModel.vehicleTypeStr
|
||
annotationView.bigWorkingCountlabel.isHidden = !vehicleModel.shouldShowWorkingCount
|
||
if let workingCount = vehicleModel.workingCount {
|
||
annotationView.bigWorkingCountlabel.text = String(workingCount)
|
||
}
|
||
annotationView.titleLabel.backgroundColor = .hex("FFFFFF")
|
||
}else{
|
||
annotationView.bigImageView.isHidden = true
|
||
annotationView.bigStateLabel.isHidden = true
|
||
if shouldShowSmallAnnotation == true {
|
||
annotationView.smallImageView.isHidden = false
|
||
annotationView.middleImageView.isHidden = true
|
||
annotationView.middleStateLabel.isHidden = true
|
||
annotationView.titleLabel.isHidden = true
|
||
annotationView.smallImageView.backgroundColor = backgroundColor
|
||
}else{
|
||
annotationView.smallImageView.isHidden = true
|
||
annotationView.middleImageView.isHidden = false
|
||
annotationView.middleStateLabel.isHidden = false
|
||
annotationView.titleLabel.isHidden = false
|
||
annotationView.middleImageView.image = middleImage
|
||
annotationView.middleStateLabel.text = vehicleModel.vehicleTypeStr
|
||
annotationView.middleWorkingCountlabel.isHidden = !vehicleModel.shouldShowWorkingCount
|
||
if let workingCount = vehicleModel.workingCount {
|
||
annotationView.middleWorkingCountlabel.text = String(workingCount)
|
||
}
|
||
}
|
||
annotationView.titleLabel.backgroundColor = .clear
|
||
}
|
||
|
||
annotationView.titleLabel.text = vehicleModel.vehicleName
|
||
}
|
||
|
||
func showListDetail(vehicleModel: VehicleMonitorListDataModel.ItemModel) {
|
||
selectedModel = vehicleModel
|
||
|
||
vehicleMonitoringListDetailView.stateLabel.text = vehicleModel.vehicleTypeStr
|
||
vehicleMonitoringListDetailView.nameLabel.text = vehicleModel.driverName
|
||
vehicleMonitoringListDetailView.vehicleLabel.text = vehicleModel.vehicleName
|
||
|
||
switch vehicleModel.vehicleStatus?.code {
|
||
case VehicleStatusCodeEnum.offLine.rawValue,VehicleStatusCodeEnum.lostConnection.rawValue:
|
||
vehicleMonitoringListDetailView.icon.image = UIImage(named: "vehicleMonitor_offline_cell_flag_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.onLine.rawValue,VehicleStatusCodeEnum.leisure.rawValue:
|
||
vehicleMonitoringListDetailView.icon.image = UIImage(named: "vehicleMonitor_empty_cell_flag_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.busy.rawValue:
|
||
vehicleMonitoringListDetailView.icon.image = UIImage(named: "vehicleMonitor_busy_cell_onlne_bg")
|
||
break
|
||
case VehicleStatusCodeEnum.BuyBusy.rawValue:
|
||
vehicleMonitoringListDetailView.icon.image = UIImage(named: "vehicleMonitor_busy_cell_onlne_bg")
|
||
break
|
||
default:
|
||
vehicleMonitoringListDetailView.icon.image = UIImage(named: "vehicleMonitor_offline_cell_flag_bg")
|
||
break
|
||
}
|
||
|
||
vehicleMonitoringListDetailView.updateData(taskModels: vehicleModel.taskList ?? [])
|
||
|
||
/// 视频按钮显示规则
|
||
if let number = vehicleModel.number, number.isEmpty == false {
|
||
vehicleMonitoringListDetailView.videoButton.isHidden = false
|
||
vehicleMonitoringListDetailView.videoButton.snp.updateConstraints { make in
|
||
make.left.equalTo(vehicleMonitoringListDetailView.settingButton.snp.right).offset(auto(10))
|
||
make.width.equalTo(auto(23))
|
||
}
|
||
}else{
|
||
vehicleMonitoringListDetailView.videoButton.isHidden = true
|
||
vehicleMonitoringListDetailView.videoButton.snp.updateConstraints { make in
|
||
make.left.equalTo(vehicleMonitoringListDetailView.settingButton.snp.right).offset(0)
|
||
make.width.equalTo(0)
|
||
}
|
||
}
|
||
|
||
if let terminalType = vehicleModel.terminalType {
|
||
vehicleMonitoringListDetailView.locationLabel.text = "定位:\(terminalType)"
|
||
}
|
||
|
||
var workScheduleString = ""
|
||
if let startTime = vehicleModel.startTime, let endTime = vehicleModel.endTime {
|
||
workScheduleString = "\(startTime)-\(endTime)"
|
||
}
|
||
if workScheduleString.count > 0 {
|
||
if let rosterType = vehicleModel.rosterType {
|
||
workScheduleString = workScheduleString.appending("/\(rosterType)")
|
||
}
|
||
}else{
|
||
workScheduleString = vehicleModel.rosterType ?? ""
|
||
}
|
||
if workScheduleString.count == 0 {
|
||
vehicleMonitoringListDetailView.workScheduleTitle.text = nil
|
||
vehicleMonitoringListDetailView.workScheduleContent.text = nil
|
||
}else{
|
||
vehicleMonitoringListDetailView.workScheduleTitle.text = "排班:"
|
||
vehicleMonitoringListDetailView.workScheduleContent.text = workScheduleString
|
||
}
|
||
|
||
/// 当为max时收回pannelView
|
||
if pannelPanGes.panGesValue.expandLevel == .max {
|
||
previousStateOfPannelView = .max
|
||
pannelPanGes.expand(.default)
|
||
}
|
||
|
||
/// 改变约束
|
||
vehicleMonitoringListDetailView.snp.updateConstraints({ make in
|
||
make.left.equalTo(vehicleMonitoringView.snp.right).offset(-vehicleMonitoringView.width)
|
||
})
|
||
UIView.animate(withDuration: 0.25) {[weak self] in
|
||
self?.view.layoutIfNeeded()
|
||
}
|
||
|
||
isListDetailShowed = true
|
||
}
|
||
|
||
func hideListDetail() {
|
||
vehicleMonitoringListDetailView.snp.updateConstraints({ make in
|
||
make.left.equalTo(vehicleMonitoringView.snp.right).offset(0)
|
||
})
|
||
UIView.animate(withDuration: 0.25) {[weak self] in
|
||
self?.view.layoutIfNeeded()
|
||
}
|
||
|
||
if previousStateOfPannelView == .max {
|
||
pannelPanGes.expand(.max)
|
||
previousStateOfPannelView = .min
|
||
}
|
||
|
||
isListDetailShowed = false
|
||
}
|
||
|
||
func hideIncidentLocation() {
|
||
let annotations = vehicleMonitoringView.maMapView.maMapView.annotations.filter { item in
|
||
let annotation = item as? MAPointAnnotation
|
||
return annotation?.annotationClass == VehicleMonitoringIncidentLocationAnnotationView.self
|
||
}
|
||
vehicleMonitoringView.maMapView.maMapView.removeAnnotations(annotations)
|
||
}
|
||
|
||
func showMapCenter(with vehicleModel: VehicleMonitorListDataModel.ItemModel) {
|
||
/// 将镜头设置为选中的item,需要修改锚点
|
||
if let lat = vehicleModel.lat,let lon = vehicleModel.lon {
|
||
modifyMapAnchor()
|
||
|
||
vehicleMonitoringView.maMapView.maMapView.setCenter(CLLocationCoordinate2D(latitude: Double(lat) ?? 0, longitude: Double(lon) ?? 0), animated: true)
|
||
}
|
||
}
|
||
|
||
func modifyMapAnchor() {
|
||
let mapHeight = vehicleMonitoringView.maMapView.height
|
||
var deltaH = 0.0
|
||
if pannelPanGes.panGesValue.expandLevel == .max {
|
||
deltaH = mapHeight - pannelPanGes.panGesValue.maxDisplayHeight
|
||
}else if pannelPanGes.panGesValue.expandLevel == .default {
|
||
deltaH = mapHeight - pannelPanGes.panGesValue.defaultDisplayHeight
|
||
}else{
|
||
deltaH = mapHeight - pannelPanGes.panGesValue.minDisplayHeight
|
||
}
|
||
let scale = (deltaH/2) / (mapHeight/2)
|
||
vehicleMonitoringView.maMapView.maMapView.screenAnchor = CGPoint(x: 0.5, y: 0.5 * scale)
|
||
}
|
||
|
||
func resetSelectedOfData() {
|
||
currentTableView = nil
|
||
selectedTableView = nil
|
||
selectedVehicleId = nil
|
||
selectedModel = nil
|
||
}
|
||
}
|
||
|
||
open class VehicleMonitoringController : ZDViewController {
|
||
/// 当控制器有tabBar时需要记录值
|
||
struct SafeAreaInsets {
|
||
static var safeAreaInsetsTop = 0.0
|
||
static var safeAreaInsetsBottom = 0.0
|
||
}
|
||
|
||
private let vehicleMonitoringView = VehicleMonitoringView(titles:[])
|
||
private let vehicleMonitoringListDetailView = VehicleMonitoringListDetailView(taskModels: [])
|
||
public lazy var categoryContainerView = JXCategoryListContainerView(type: .scrollView, delegate: self)
|
||
private let pannelPanGes = DDUIPanGestureRecognizer.init() /// 用于pannel的拖动效果
|
||
private let reloadRelay = ReplayRelay<Any?>.create(bufferSize: 1) /// 仅刷新列表数据
|
||
private var dataModel : VehicleMonitorListDataModel? /// 总数据
|
||
private var mapModel : [VehicleMonitorListDataModel.ItemModel]? /// category列表数据
|
||
public var zIndex = 0 /// 用于annotation的位置靠前靠后
|
||
|
||
private var currentTableView : DDTableView? /// 用于选中
|
||
private var selectedVehicleId : Int? /// 用于选中
|
||
private var selectedTableView : DDTableView? /// 用于选中
|
||
private var selectedModel : VehicleMonitorListDataModel.ItemModel? /// 用于选中
|
||
|
||
private var previousStateOfPannelView : DDUIPanGestureRecognizer.ExpandLevel = .min /// 用于记录显示详情前,pannelview的弹出状态为max时,返回时保持这个状态
|
||
private var isListDetailShowed : Bool = false /// 用于判断同一个详情是否被重复点击
|
||
|
||
private var shouldShowSmallAnnotation : Bool? = false /// 用于标记是否需要显示最小的annotation
|
||
private var isShowSmallAnnotation : Bool? = false /// 用于标记是否已经显示最小的annotation
|
||
|
||
private var defaultCoordinate : CLLocationCoordinate2D? /// list为0默认展示该位置
|
||
|
||
private let messageTapGes = UITapGestureRecognizer() /// 消息按钮点击事件
|
||
private let messageView = MessageView() /// 消息按钮
|
||
public let refreshButton = DDButton.dd_initCustom() /// 刷新按钮
|
||
|
||
private var preRefreshRelay = ReplayRelay<Any?>.create(bufferSize: 1) /// 刷新列表数据以及消息的数据
|
||
private let vehicleLogoutView = VehicleLogoutView() /// 车辆退出界面
|
||
private let vehicleConfigView = VehicleMonitoringConfigView()
|
||
private var showVehicleEntryRelay = ReplayRelay<VehicleMonitorListDataModel.ItemModel?>.create(bufferSize: 1) /// 车辆退出点击事件
|
||
private var vehicleLogoutModel : VehicleMonitorListDataModel.ItemModel?
|
||
private var vehicleLogoutRelay = ReplayRelay<VehicleMonitorListDataModel.ItemModel?>.create(bufferSize: 1)
|
||
|
||
private var alarmList : [AlarmListDataModel] = []
|
||
private let disposeBag = DisposeBag()
|
||
|
||
open override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
dd_navigationItemTitle = "车辆监控"
|
||
dd_navigationBarTitleTextAttributes = [.foregroundColor : UIColor.white(alpha: 0.7),.font:UIFont.mediumFont(17)]
|
||
dd_navigationBarBarButtonItemAttributes = [.foregroundColor : UIColor.white]
|
||
navigationItem.leftBarButtonItems = nil
|
||
|
||
addSubviews()
|
||
addAction()
|
||
}
|
||
|
||
func addSubviews() {
|
||
view.addSubview(vehicleMonitoringView)
|
||
|
||
view.addSubview(vehicleMonitoringListDetailView)
|
||
vehicleMonitoringListDetailView.snp.makeConstraints { make in
|
||
make.left.equalTo(vehicleMonitoringView.snp.right)
|
||
make.bottom.equalTo(vehicleMonitoringView)
|
||
make.width.equalTo(vehicleMonitoringView)
|
||
make.height.equalTo(vehicleMonitoringListDetailViewHeight)
|
||
}
|
||
|
||
CustomMapStyle.customMap(vehicleMonitoringView.maMapView.maMapView)
|
||
vehicleMonitoringView.maMapView.delegate = self
|
||
vehicleMonitoringView.maMapView.maMapView.showsUserLocation = true
|
||
vehicleMonitoringView.maMapView.maMapView.userTrackingMode = .follow
|
||
vehicleMonitoringView.maMapView.maMapView.customizeUserLocationAccuracyCircleRepresentation = true
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.delegate = self
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.listContainer = categoryContainerView
|
||
pannelPanGes.panGesValue.from = .bottom
|
||
pannelPanGes.expandLevelChangedHandler = {[weak self] old, new in
|
||
self?.modifyMapAnchor()
|
||
}
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.addGestureRecognizer(pannelPanGes)
|
||
|
||
messageView.titleLabel.text = "消息"
|
||
messageView.addGestureRecognizer(messageTapGes)
|
||
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: messageView)
|
||
messageView.snp.makeConstraints { make in
|
||
make.height.equalTo(40)
|
||
make.width.greaterThanOrEqualTo(40)
|
||
}
|
||
|
||
refreshButton.setTitle("刷新", for: .normal)
|
||
refreshButton.setTitleColor(.hex("FFFFFF").alpha(0.7), for: .normal)
|
||
refreshButton.titleLabel?.font = .mediumFont(auto(14))
|
||
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: refreshButton)
|
||
|
||
if let categoryContainerView {
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.radiusView.addSubview(categoryContainerView)
|
||
}
|
||
}
|
||
|
||
open override func viewSafeAreaInsetsDidChange() {
|
||
super.viewSafeAreaInsetsDidChange()
|
||
SafeAreaInsets.safeAreaInsetsTop = view.safeAreaInsets.top
|
||
if view.safeAreaInsets.bottom > 0 {
|
||
SafeAreaInsets.safeAreaInsetsBottom = view.safeAreaInsets.bottom
|
||
}
|
||
|
||
vehicleMonitoringView.snp.remakeConstraints { make in
|
||
make.left.right.equalToSuperview()
|
||
make.top.equalToSuperview().offset(SafeAreaInsets.safeAreaInsetsTop)
|
||
make.bottom.equalToSuperview().offset(-SafeAreaInsets.safeAreaInsetsBottom)
|
||
}
|
||
|
||
let vehicleMonitoringPannelViewCornerRadius = auto(16)
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.layer.cornerRadius = vehicleMonitoringPannelViewCornerRadius
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.layer.masksToBounds = true
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.snp.remakeConstraints { make in
|
||
make.top.equalToSuperview().priority(.high)
|
||
make.left.right.equalToSuperview()
|
||
make.height.equalTo(vehicleMonitoringPannelCategoryViewHeight)
|
||
}
|
||
|
||
vehicleMonitoringListDetailView.layer.cornerRadius = vehicleMonitoringPannelViewCornerRadius
|
||
vehicleMonitoringListDetailView.layer.masksToBounds = true
|
||
|
||
categoryContainerView?.snp.remakeConstraints({ make in
|
||
make.top.equalTo(vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.snp.bottom)
|
||
make.left.right.equalToSuperview()
|
||
make.bottom.equalToSuperview()
|
||
})
|
||
|
||
let minDisplayHeight = vehicleMonitoringPannelCategoryViewHeight
|
||
let maxDisplayHeight = view.height - SafeAreaInsets.safeAreaInsetsTop - SafeAreaInsets.safeAreaInsetsBottom - auto(150)
|
||
let defaultDisplayHeight = vehicleMonitoringListDetailViewHeight
|
||
vehicleMonitoringView.maMapView.snp.remakeConstraints { make in
|
||
make.left.right.equalToSuperview()
|
||
make.top.equalToSuperview()
|
||
make.bottom.equalToSuperview().offset(-vehicleMonitoringPannelCategoryViewHeight + vehicleMonitoringPannelViewCornerRadius)
|
||
}
|
||
|
||
if pannelPanGes.panGesValue.expandLevel == .max {
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.snp.remakeConstraints { make in
|
||
make.left.right.equalToSuperview()
|
||
make.height.equalTo(maxDisplayHeight)
|
||
make.bottom.equalToSuperview()
|
||
}
|
||
}else if pannelPanGes.panGesValue.expandLevel == .min {
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.snp.remakeConstraints { make in
|
||
make.left.right.equalToSuperview()
|
||
make.height.equalTo(maxDisplayHeight)
|
||
make.bottom.equalToSuperview().offset(maxDisplayHeight - minDisplayHeight)
|
||
}
|
||
}else if pannelPanGes.panGesValue.expandLevel == .default {
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.snp.remakeConstraints { make in
|
||
make.left.right.equalToSuperview()
|
||
make.height.equalTo(maxDisplayHeight)
|
||
make.bottom.equalToSuperview().offset(maxDisplayHeight - defaultDisplayHeight)
|
||
}
|
||
}
|
||
|
||
pannelPanGes.panGesValue.minDisplayHeight = minDisplayHeight
|
||
pannelPanGes.panGesValue.maxDisplayHeight = maxDisplayHeight
|
||
pannelPanGes.panGesValue.defaultDisplayHeight = defaultDisplayHeight
|
||
|
||
/// categoryView会影响导航栏的背景色
|
||
dd_navigationBarBackgroundColor = .hex("354683")
|
||
}
|
||
|
||
open override func viewWillLayoutSubviews() {
|
||
super.viewWillLayoutSubviews()
|
||
vehicleMonitoringView.maMapView.maMapView.logoCenter = CGPoint(x: vehicleMonitoringView.maMapView.maMapView.logoCenter.x, y: CGRectGetMaxY(vehicleMonitoringView.maMapView.maMapView.frame) - 30)
|
||
}
|
||
|
||
open override func viewDidAppear(_ animated: Bool) {
|
||
super.viewDidAppear(animated)
|
||
}
|
||
|
||
open override func viewWillDisappear(_ animated: Bool) {
|
||
super.viewWillDisappear(animated)
|
||
hideListDetail()
|
||
resetSelectedOfData()
|
||
resetSelectedOfDataModel()
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.reloadDataWithoutListContainer()
|
||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.listContainer.reloadData()
|
||
if vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.titles.count > 0 {
|
||
categoryView(vehicleMonitoringView.vehicleMonitoringPannelView.categoryView, didSelectedItemAt: vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.selectedIndex)
|
||
}
|
||
}
|
||
|
||
open override func reloadData() {
|
||
super.reloadData()
|
||
preRefreshRelay.accept(nil)
|
||
}
|
||
}
|
||
|
||
// MARK: UI
|
||
open class VehicleMonitoringView : DDView {
|
||
public let vehicleMonitoringPannelView : VehicleMonitoringPannelView
|
||
public let maMapView : DDMAMapView
|
||
public let coverView : DDView
|
||
public let tapGes : UITapGestureRecognizer
|
||
public let panGes : UIPanGestureRecognizer
|
||
public let offlineView : VehicleDeviceOffLineView
|
||
public let alarmView : VehicleAlarmView
|
||
public init(titles: [String]) {
|
||
vehicleMonitoringPannelView = VehicleMonitoringPannelView(titles:titles)
|
||
maMapView = DDMAMapView()
|
||
coverView = DDView()
|
||
tapGes = UITapGestureRecognizer()
|
||
panGes = UIPanGestureRecognizer()
|
||
offlineView = VehicleDeviceOffLineView()
|
||
alarmView = VehicleAlarmView()
|
||
super.init(frame: .zero)
|
||
|
||
maMapView.maMapView.isRotateCameraEnabled = false
|
||
addSubview(maMapView)
|
||
|
||
offlineView.offlineIconImageView.image = UIImage(named: "vehicleMonitoring_offline_icon")
|
||
offlineView.backgroundColor = .dd_hex(light: "FB8958", dark: "FB8958")
|
||
offlineView.layer.cornerRadius = 6
|
||
offlineView.isHidden = true
|
||
addSubview(offlineView)
|
||
alarmView.imageView.image = UIImage(named: "vehicleMonitoring_alarm")
|
||
alarmView.isHidden = true
|
||
addSubview(alarmView)
|
||
coverView.addGestureRecognizer(tapGes)
|
||
coverView.addGestureRecognizer(panGes)
|
||
coverView.isHidden = true
|
||
addSubview(coverView)
|
||
addSubview(vehicleMonitoringPannelView)
|
||
|
||
coverView.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
|
||
alarmView.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(10)
|
||
make.right.equalToSuperview().offset(-10)
|
||
}
|
||
|
||
offlineView.snp.makeConstraints { make in
|
||
make.centerY.equalTo(alarmView)
|
||
make.centerX.equalToSuperview()
|
||
make.height.equalTo(35)
|
||
make.width.equalTo(200)
|
||
}
|
||
}
|
||
|
||
required public init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
open class VehicleDeviceOffLineView : DDView {
|
||
let offlineIconImageView : DDImageView
|
||
let offLineLabel : VerticalLoopScrollLabel
|
||
public override init(frame: CGRect) {
|
||
offlineIconImageView = DDImageView()
|
||
offLineLabel = VerticalLoopScrollLabel()
|
||
super.init(frame: frame)
|
||
addSubview(offlineIconImageView)
|
||
addSubview(offLineLabel)
|
||
|
||
offlineIconImageView.snp.makeConstraints { make in
|
||
make.left.equalTo(15)
|
||
make.centerY.equalToSuperview()
|
||
}
|
||
|
||
offLineLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(offlineIconImageView.snp.right).offset(10)
|
||
make.right.equalToSuperview().offset(-10)
|
||
make.top.bottom.equalToSuperview().inset(8)
|
||
}
|
||
|
||
}
|
||
|
||
@MainActor required public init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
open class VehicleAlarmView : DDView {
|
||
public let imageView : DDImageView
|
||
public let count : DDLabel
|
||
|
||
public override init(frame: CGRect) {
|
||
self.imageView = DDImageView()
|
||
self.count = DDLabel()
|
||
super.init(frame: frame)
|
||
|
||
addSubview(imageView)
|
||
count.layer.cornerRadius = 1
|
||
count.layer.borderColor = UIColor.dd_hex(light: "FFFFFF", dark: "FFFFFF").cgColor
|
||
count.layer.borderWidth = 0.8
|
||
count.layer.masksToBounds = true
|
||
count.backgroundColor = .dd_hex(light: "F93D3D", dark: "F93D3D")
|
||
count.textColor = .dd_hex(light: "FFFFFF", dark: "FFFFFF")
|
||
count.font = .dd_systemFont(ofSize: 12, weight: .semibold)
|
||
addSubview(count)
|
||
|
||
imageView.snp.makeConstraints { make in
|
||
make.left.top.bottom.equalToSuperview()
|
||
make.width.height.equalTo(50)
|
||
}
|
||
|
||
count.snp.makeConstraints { make in
|
||
make.left.equalTo(imageView.snp.right).offset(-15)
|
||
make.right.lessThanOrEqualToSuperview()
|
||
make.top.equalTo(imageView.snp.top)
|
||
}
|
||
|
||
}
|
||
|
||
@MainActor required public init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
open class VehicleMonitoringPannelView : DDView {
|
||
public let radiusView : DDView
|
||
public let categoryView : JXCategoryNumberView
|
||
|
||
public init(titles:[String]) {
|
||
radiusView = DDView()
|
||
categoryView = JXCategoryNumberView.init()
|
||
categoryView.titles = titles
|
||
super.init(frame: .zero)
|
||
backgroundColor = .hex("FBFBFB")
|
||
radiusView.backgroundColor = .clear
|
||
addSubview(radiusView)
|
||
|
||
categoryView.titleNumberOfLines = 1
|
||
categoryView.titleColor = .hex("737373").alpha(0.55)
|
||
categoryView.titleSelectedColor = .hex("3678FF")
|
||
categoryView.titleFont = .mediumFont(auto(14))
|
||
categoryView.backgroundColor = .hex("FBFBFB")
|
||
let indicator = JXCategoryIndicatorLineView()
|
||
indicator.indicatorColor = .hex("3678FF")
|
||
indicator.verticalMargin = 0
|
||
categoryView.indicators = [indicator]
|
||
|
||
categoryView.numberBackgroundColor = .red
|
||
categoryView.numberLabelOffset = CGPoint(x: 5, y: 0)
|
||
radiusView.addSubview(categoryView)
|
||
|
||
radiusView.snp.makeConstraints { make in
|
||
make.top.left.right.equalToSuperview()
|
||
make.bottom.equalToSuperview()
|
||
}
|
||
}
|
||
|
||
required public init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
}
|
||
|
||
open class VehicleMonitoringIncidentLocationAnnotationView : MAAnnotationView {
|
||
|
||
}
|
||
|
||
open class VehicleMonitoringPointAnnotation : MAAnnotationView {
|
||
public let clearView : DDView
|
||
public var disposeBag : DisposeBag
|
||
public var smallImageView : DDImageView
|
||
public var middleImageView : DDImageView
|
||
public var bigImageView : DDImageView
|
||
public var titleLabel : DDLabel
|
||
public var middleStateLabel : DDLabel
|
||
public var bigStateLabel : DDLabel
|
||
public var middleWorkingCountlabel : DDLabel
|
||
public var bigWorkingCountlabel : DDLabel
|
||
override init!(annotation: MAAnnotation!, reuseIdentifier: String!) {
|
||
clearView = DDView.init()
|
||
disposeBag = DisposeBag()
|
||
smallImageView = DDImageView()
|
||
middleImageView = DDImageView()
|
||
bigImageView = DDImageView()
|
||
titleLabel = DDLabel.dd_init(withText: "", font: .mediumFont(11), textColor: .hex("03030F"))
|
||
middleStateLabel = DDLabel.dd_init(withText: "", font: .mediumFont(10), textColor: .white)
|
||
bigStateLabel = DDLabel.dd_init(withText: "", font: .mediumFont(18), textColor: .white)
|
||
middleWorkingCountlabel = DDLabel.dd_init(withText: "", font: .mediumFont(7), textColor: .white)
|
||
bigWorkingCountlabel = DDLabel.dd_init(withText: "", font: .mediumFont(9), textColor: .white)
|
||
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
|
||
setUpSubviews()
|
||
}
|
||
|
||
required public init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
open override func prepareForReuse() {
|
||
super.prepareForReuse()
|
||
disposeBag = DisposeBag()
|
||
}
|
||
|
||
func setUpSubviews(){
|
||
clearView.isUserInteractionEnabled = false
|
||
addSubview(clearView)
|
||
|
||
smallImageView.layer.cornerRadius = auto(5)
|
||
smallImageView.layer.borderColor = UIColor.white.cgColor
|
||
smallImageView.layer.borderWidth = 1
|
||
smallImageView.backgroundColor = .hex("858585")
|
||
clearView.addSubview(smallImageView)
|
||
|
||
titleLabel.textAlignment = .center
|
||
clearView.addSubview(titleLabel)
|
||
|
||
middleImageView.layer.cornerRadius = auto(11)
|
||
middleImageView.layer.borderColor = UIColor.white.cgColor
|
||
middleImageView.layer.borderWidth = 1
|
||
middleImageView.backgroundColor = .hex("858585")
|
||
clearView.addSubview(middleImageView)
|
||
middleImageView.addSubview(middleStateLabel)
|
||
middleWorkingCountlabel.backgroundColor = .hex("F93D3D")
|
||
middleWorkingCountlabel.textAlignment = .center
|
||
middleWorkingCountlabel.layer.borderColor = UIColor.white.cgColor
|
||
middleWorkingCountlabel.layer.borderWidth = 1
|
||
middleImageView.addSubview(middleWorkingCountlabel)
|
||
|
||
clearView.addSubview(bigImageView)
|
||
bigImageView.addSubview(bigStateLabel)
|
||
bigWorkingCountlabel.backgroundColor = .hex("F93D3D")
|
||
bigWorkingCountlabel.textAlignment = .center
|
||
bigWorkingCountlabel.layer.borderColor = UIColor.white.cgColor
|
||
bigWorkingCountlabel.layer.borderWidth = 1
|
||
bigImageView.addSubview(bigWorkingCountlabel)
|
||
|
||
clearView.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
|
||
smallImageView.snp.makeConstraints { make in
|
||
make.centerX.centerY.equalToSuperview()
|
||
make.width.height.equalTo(auto(10))
|
||
}
|
||
|
||
titleLabel.snp.makeConstraints { make in
|
||
make.bottom.left.right.equalToSuperview()
|
||
}
|
||
|
||
middleImageView.snp.makeConstraints { make in
|
||
make.centerX.equalToSuperview()
|
||
make.top.equalToSuperview().priority(.high)
|
||
make.width.height.equalTo(auto(22))
|
||
make.bottom.equalTo(titleLabel.snp.top)
|
||
}
|
||
|
||
middleStateLabel.snp.makeConstraints { make in
|
||
make.centerX.centerY.equalTo(middleImageView)
|
||
}
|
||
|
||
middleWorkingCountlabel.layer.cornerRadius = auto(5)
|
||
middleWorkingCountlabel.layer.masksToBounds = true
|
||
middleWorkingCountlabel.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(-auto(5))
|
||
make.right.equalToSuperview().offset(auto(5))
|
||
make.width.height.equalTo(10)
|
||
}
|
||
|
||
bigImageView.snp.makeConstraints { make in
|
||
make.centerX.equalToSuperview()
|
||
make.top.equalToSuperview().priority(.high)
|
||
make.width.equalTo(auto(42))
|
||
make.height.equalTo(auto(50))
|
||
make.bottom.equalTo(titleLabel.snp.top)
|
||
}
|
||
|
||
bigStateLabel.snp.makeConstraints { make in
|
||
make.centerX.equalToSuperview()
|
||
make.centerY.equalToSuperview().offset(-auto(4))
|
||
}
|
||
|
||
bigWorkingCountlabel.layer.cornerRadius = auto(7.5)
|
||
bigWorkingCountlabel.layer.masksToBounds = true
|
||
bigWorkingCountlabel.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(-auto(2.5))
|
||
make.right.equalToSuperview().offset(auto(2.5))
|
||
make.width.height.equalTo(15)
|
||
}
|
||
}
|
||
}
|
||
|
||
class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDelegate, JXCategoryViewDelegate {
|
||
func number(ofListsInlistContainerView listContainerView: JXCategoryListContainerView!) -> Int {
|
||
return taskModels.count
|
||
}
|
||
|
||
func listContainerView(_ listContainerView: JXCategoryListContainerView!, initListFor index: Int) -> JXCategoryListContentViewDelegate! {
|
||
let view = VMLDContainerView()
|
||
view.updateData(taskModel: taskModels[index])
|
||
view.orderNumButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] _ in
|
||
if let taskModel = self?.taskModels[index] {
|
||
self?.showOrderDetailHandler?(taskModel)
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
return view
|
||
}
|
||
|
||
func categoryView(_ categoryView: JXCategoryBaseView!, didSelectedItemAt index: Int) {
|
||
pageNumLabel.text = "\(index + 1)/\(taskModels.count)"
|
||
let taskModel = taskModels[index]
|
||
if let vehiclePointLatitude = taskModel.vehiclePointLatitude, let vehiclePointLongitude = taskModel.vehiclePointLongitude {
|
||
showIncidentLocationHandler?(CLLocationCoordinate2D(latitude: vehiclePointLatitude, longitude: vehiclePointLongitude),(taskModel.destinationLatitude != nil && taskModel.destinationLongitude != nil) ? CLLocationCoordinate2D(latitude: taskModel.destinationLatitude!, longitude: taskModel.destinationLongitude!) : nil)
|
||
}
|
||
}
|
||
|
||
public var taskModels : [VehicleMonitorListDataModel.TaskModel]
|
||
public let backButton : DDButton
|
||
public let icon : DDImageView
|
||
public let stateLabel : DDLabel
|
||
public let vehicleLabel : DDLabel
|
||
public let settingButton : DDButton
|
||
public let videoButton : DDButton
|
||
public let locationLabel : DDLabel
|
||
public let workScheduleTitle : DDLabel
|
||
public let workScheduleContent : DDLabel
|
||
public let nameLabel : DDLabel
|
||
public let callButton : DDButton
|
||
public let containerView : DDView
|
||
public var categoryView : JXCategoryTitleView
|
||
public lazy var categoryContainerView = JXCategoryListContainerView(type: .scrollView, delegate: self)
|
||
public let pageNumImageView : DDImageView
|
||
public let pageNumLabel : DDLabel
|
||
public let previousButton : DDButton
|
||
public let nextButton : DDButton
|
||
public var emptyLabel : DDLabel
|
||
public let disposeBag = DisposeBag()
|
||
public var showIncidentLocationHandler : ((CLLocationCoordinate2D,CLLocationCoordinate2D?) -> Void)?
|
||
public var showOrderDetailHandler : ((VehicleMonitorListDataModel.TaskModel) -> Void)?
|
||
|
||
public init(taskModels: [VehicleMonitorListDataModel.TaskModel]) {
|
||
self.taskModels = taskModels
|
||
backButton = DDButton.dd_initCustom()
|
||
backButton.setImage(UIImage(named: "vehicleMonitoring_back"), for: .normal)
|
||
icon = DDImageView()
|
||
stateLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(10)), textColor: .white)
|
||
vehicleLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(14)), textColor: .hex("11142F"))
|
||
settingButton = DDButton.dd_initCustom()
|
||
settingButton.setBackgroundImage(UIImage(named: "vehicleMonitoring_setting"), for: .normal)
|
||
videoButton = DDButton.dd_initCustom()
|
||
videoButton.setBackgroundImage(UIImage(named: "vehicleMonitoring_video_icon"), for: .normal)
|
||
locationLabel = DDLabel.dd_init(withText: "", font: .regularFont(12), textColor: .hex("11142F"))
|
||
workScheduleTitle = DDLabel.dd_init(withText: "", font: .regularFont(12), textColor: .hex("11142F"))
|
||
workScheduleContent = DDLabel.dd_init(withText: "", font: .regularFont(12), textColor: .hex("11142F"))
|
||
nameLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .hex("11142F"))
|
||
callButton = DDButton.dd_initCustom()
|
||
callButton.setBackgroundImage(UIImage(named: "vehicleMonitor_call_cell"), for: .normal)
|
||
containerView = DDView()
|
||
categoryView = JXCategoryTitleView.init()
|
||
pageNumImageView = DDImageView(image: UIImage(named: "vehicleMonitor_pageNum_bg"))
|
||
pageNumLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(8)), textColor: .white)
|
||
previousButton = DDButton.dd_initCustom()
|
||
previousButton.setImage(UIImage(named: "vehicleMonitoring_previous_gray"), for: .normal)
|
||
nextButton = DDButton.dd_initCustom()
|
||
nextButton.setImage(UIImage(named: "vehicleMonitoring_next_gray"), for: .normal)
|
||
emptyLabel = DDLabel.dd_init(withText: "暂无执行中订单", font: .mediumFont(auto(18)), textColor: .hex("11142F").alpha(0.6))
|
||
super.init(frame: .zero)
|
||
backgroundColor = .white
|
||
layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]
|
||
|
||
backgroundColor = .hex("F2F7FA")
|
||
addSubview(backButton)
|
||
addSubview(icon)
|
||
stateLabel.textAlignment = .center
|
||
icon.addSubview(stateLabel)
|
||
addSubview(vehicleLabel)
|
||
addSubview(settingButton)
|
||
addSubview(videoButton)
|
||
addSubview(locationLabel)
|
||
addSubview(nameLabel)
|
||
addSubview(callButton)
|
||
addSubview(workScheduleTitle)
|
||
addSubview(workScheduleContent)
|
||
containerView.backgroundColor = .hex("FAFAFA")
|
||
containerView.layer.cornerRadius = auto(5)
|
||
containerView.layer.masksToBounds = true
|
||
addSubview(containerView)
|
||
categoryView.delegate = self
|
||
if let categoryContainerView = self.categoryContainerView {
|
||
containerView.addSubview(categoryContainerView)
|
||
categoryView.listContainer = categoryContainerView
|
||
}
|
||
|
||
categoryContainerView?.addSubview(pageNumImageView)
|
||
pageNumLabel.textAlignment = .center
|
||
pageNumImageView.addSubview(pageNumLabel)
|
||
categoryContainerView?.addSubview(previousButton)
|
||
categoryContainerView?.addSubview(nextButton)
|
||
|
||
containerView.addSubview(emptyLabel)
|
||
|
||
containerView.snp.makeConstraints { make in
|
||
make.left.right.equalToSuperview().inset(auto(7))
|
||
make.top.equalTo(workScheduleContent.snp.bottom).offset(auto(5))
|
||
make.bottom.equalToSuperview().offset(-auto(10))
|
||
}
|
||
|
||
categoryContainerView?.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
|
||
emptyLabel.snp.makeConstraints { make in
|
||
make.centerX.centerY.equalToSuperview()
|
||
}
|
||
|
||
pageNumImageView.snp.makeConstraints { make in
|
||
make.left.top.equalToSuperview()
|
||
make.width.equalTo(auto(20))
|
||
make.height.equalTo(auto(14))
|
||
}
|
||
|
||
pageNumLabel.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
|
||
previousButton.snp.makeConstraints { make in
|
||
make.left.equalToSuperview().offset(-auto(10))
|
||
make.centerY.equalToSuperview()
|
||
make.width.equalTo(auto(30))
|
||
make.height.equalTo(auto(40))
|
||
}
|
||
|
||
nextButton.snp.makeConstraints { make in
|
||
make.right.equalToSuperview().offset(auto(10))
|
||
make.centerY.equalToSuperview()
|
||
make.width.equalTo(auto(30))
|
||
make.height.equalTo(auto(40))
|
||
}
|
||
|
||
backButton.snp.makeConstraints { make in
|
||
make.left.equalTo(0)
|
||
make.top.equalTo(0)
|
||
make.width.height.equalTo(auto(40))
|
||
}
|
||
|
||
icon.snp.makeConstraints { make in
|
||
make.left.equalTo(backButton.snp.right).offset(0)
|
||
make.centerY.equalTo(backButton)
|
||
make.width.height.equalTo(auto(20))
|
||
}
|
||
|
||
stateLabel.snp.makeConstraints { make in
|
||
make.edges.equalTo(icon)
|
||
}
|
||
|
||
vehicleLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(icon.snp.right).offset(auto(3))
|
||
make.centerY.equalTo(icon)
|
||
}
|
||
|
||
settingButton.snp.makeConstraints { make in
|
||
make.left.equalTo(vehicleLabel.snp.right).offset(auto(5))
|
||
make.centerY.equalTo(icon)
|
||
make.width.equalTo(auto(16))
|
||
make.height.equalTo(auto(14))
|
||
}
|
||
|
||
videoButton.snp.makeConstraints { make in
|
||
make.left.equalTo(settingButton.snp.right).offset(auto(10))
|
||
make.centerY.equalTo(icon)
|
||
make.width.equalTo(auto(23))
|
||
make.height.equalTo(auto(13))
|
||
}
|
||
|
||
locationLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(videoButton.snp.right).offset(auto(10))
|
||
make.centerY.equalTo(icon)
|
||
}
|
||
|
||
callButton.snp.makeConstraints { make in
|
||
make.right.equalTo(-auto(20))
|
||
make.centerY.equalTo(backButton)
|
||
make.width.height.equalTo(auto(25))
|
||
}
|
||
|
||
nameLabel.snp.makeConstraints { make in
|
||
make.right.equalTo(callButton.snp.left).offset(-auto(8))
|
||
make.centerY.equalTo(callButton)
|
||
}
|
||
|
||
workScheduleTitle.snp.makeConstraints { make in
|
||
make.top.equalTo(backButton.snp.bottom)
|
||
make.left.equalTo(icon)
|
||
}
|
||
|
||
workScheduleContent.snp.makeConstraints { make in
|
||
make.left.equalTo(workScheduleTitle.snp.right).offset(auto(10))
|
||
make.right.lessThanOrEqualToSuperview().offset(-auto(20))
|
||
make.top.equalTo(workScheduleTitle)
|
||
}
|
||
|
||
previousButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] in
|
||
if let index = self?.categoryView.selectedIndex {
|
||
if index > 0 {
|
||
let newIndex = index - 1
|
||
self?.categoryView.selectItem(at: newIndex)
|
||
}
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
nextButton.rx.tap
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onNext: {[weak self] in
|
||
if let index = self?.categoryView.selectedIndex, let allCount = self?.taskModels.count {
|
||
let validCount = allCount - 1
|
||
if index < validCount {
|
||
let newIndex = index + 1
|
||
self?.categoryView.selectItem(at: newIndex)
|
||
}
|
||
}
|
||
})
|
||
.disposed(by: disposeBag)
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
public func updateData(taskModels: [VehicleMonitorListDataModel.TaskModel]) {
|
||
self.taskModels = taskModels
|
||
let allCount = taskModels.count
|
||
if allCount > 0 {
|
||
var titles : [String] = []
|
||
for index in 0..<allCount {
|
||
titles.append("\(index)")
|
||
}
|
||
categoryView.titles = titles
|
||
emptyLabel.isHidden = true
|
||
categoryContainerView?.isHidden = false
|
||
}else{
|
||
categoryView.titles = nil
|
||
emptyLabel.isHidden = false
|
||
categoryContainerView?.isHidden = true
|
||
}
|
||
categoryView.reloadData()
|
||
|
||
if allCount > 0 {
|
||
categoryView.selectItem(at: 0)
|
||
}
|
||
}
|
||
}
|
||
|
||
class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||
var orderNumButton : UIButton
|
||
var titleLabel : DDLabel
|
||
var stateLabel : DDLabel
|
||
var line : DDView
|
||
var incidentIcon : UIImageView
|
||
var incidentLabel : DDLabel
|
||
var destIcon : UIImageView
|
||
var destLabel : DDLabel
|
||
var contractImageView : DDImageView
|
||
var contractTitle : DDLabel
|
||
var contractContent : DDLabel
|
||
var distanceFromPointLabel : DDLabel
|
||
var remainTimeLabel : DDLabel
|
||
var distanceLabel : DDLabel
|
||
var disposeBag : DisposeBag
|
||
override init(frame: CGRect) {
|
||
orderNumButton = UIButton()
|
||
orderNumButton.setTitleColor(.hex("0E76F4"), for: .normal)
|
||
orderNumButton.titleLabel?.font = .regularFont(auto(12))
|
||
titleLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .hex("000000").alpha(0.7))
|
||
stateLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(12)), textColor: .hex("09B820"))
|
||
line = DDView()
|
||
incidentIcon = UIImageView(image: UIImage(named: "vehichleMonitoring_start_16"))
|
||
incidentLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .hex("000000").alpha(0.7))
|
||
destIcon = UIImageView(image: UIImage(named: "vehichleMonitoring_terminal_16"))
|
||
destLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .hex("000000").alpha(0.7))
|
||
contractImageView = DDImageView()
|
||
contractTitle = DDLabel.dd_init(withText: "", font: .regularFont(12), textColor: .hex("11142F"))
|
||
contractContent = DDLabel.dd_init(withText: "", font: .regularFont(12), textColor: .hex("11142F"))
|
||
distanceFromPointLabel = DDLabel()
|
||
remainTimeLabel = DDLabel()
|
||
distanceLabel = DDLabel()
|
||
disposeBag = DisposeBag()
|
||
super.init(frame: frame)
|
||
|
||
addSubview(orderNumButton)
|
||
addSubview(titleLabel)
|
||
stateLabel.numberOfLines = 0
|
||
addSubview(stateLabel)
|
||
line.backgroundColor = .hex("F1F2F5")
|
||
addSubview(line)
|
||
addSubview(incidentIcon)
|
||
incidentLabel.numberOfLines = 0
|
||
incidentLabel.textAlignment = .left
|
||
addSubview(incidentLabel)
|
||
addSubview(destIcon)
|
||
destLabel.numberOfLines = 0
|
||
destLabel.textAlignment = .left
|
||
addSubview(destLabel)
|
||
addSubview(contractImageView)
|
||
addSubview(contractTitle)
|
||
contractContent.textAlignment = .right
|
||
contractContent.numberOfLines = 2
|
||
addSubview(contractContent)
|
||
addSubview(distanceFromPointLabel)
|
||
addSubview(remainTimeLabel)
|
||
addSubview(distanceLabel)
|
||
|
||
orderNumButton.snp.makeConstraints { make in
|
||
make.left.equalTo(auto(20))
|
||
make.top.equalTo(auto(15))
|
||
make.height.equalTo(auto(18))
|
||
}
|
||
|
||
titleLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||
titleLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(orderNumButton.snp.right).offset(auto(5))
|
||
make.centerY.equalTo(orderNumButton)
|
||
}
|
||
|
||
stateLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||
stateLabel.snp.makeConstraints { make in
|
||
make.right.equalTo(-auto(20))
|
||
make.centerY.equalTo(orderNumButton)
|
||
make.left.greaterThanOrEqualTo(titleLabel.snp.right).offset(auto(5))
|
||
}
|
||
|
||
line.snp.makeConstraints { make in
|
||
make.top.equalTo(orderNumButton.snp.bottom).offset(auto(15))
|
||
make.height.equalTo(1)
|
||
make.left.right.equalToSuperview().inset(auto(20))
|
||
}
|
||
|
||
contractImageView.snp.makeConstraints { make in
|
||
make.left.equalTo(orderNumButton)
|
||
make.top.equalTo(line.snp.bottom).offset(auto(5))
|
||
make.width.height.equalTo(auto(15))
|
||
}
|
||
|
||
contractTitle.snp.makeConstraints { make in
|
||
make.left.equalTo(contractImageView.snp.right).offset(auto(10))
|
||
make.centerY.equalTo(contractImageView.snp.centerY)
|
||
}
|
||
|
||
contractContent.snp.makeConstraints { make in
|
||
make.left.equalTo(contractTitle.snp.right).offset(auto(10))
|
||
make.right.equalToSuperview().offset(-auto(20))
|
||
make.centerY.equalTo(contractImageView)
|
||
}
|
||
|
||
incidentIcon.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||
incidentIcon.snp.makeConstraints { make in
|
||
make.left.equalTo(orderNumButton)
|
||
make.top.equalTo(contractImageView.snp.bottom).offset(auto(15))
|
||
}
|
||
|
||
incidentLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||
incidentLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(incidentIcon.snp.right).offset(auto(20))
|
||
make.top.equalTo(incidentIcon)
|
||
make.right.equalTo(-auto(20))
|
||
make.bottom.greaterThanOrEqualTo(incidentIcon)
|
||
}
|
||
|
||
destIcon.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||
destIcon.snp.makeConstraints { make in
|
||
make.left.equalTo(orderNumButton)
|
||
make.top.equalTo(incidentLabel.snp.bottom).offset(auto(15))
|
||
}
|
||
|
||
destLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||
destLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(destIcon.snp.right).offset(auto(20))
|
||
make.top.equalTo(destIcon)
|
||
make.right.equalTo(-auto(20))
|
||
make.bottom.greaterThanOrEqualTo(destIcon)
|
||
}
|
||
|
||
remainTimeLabel.snp.makeConstraints { make in
|
||
make.centerX.equalToSuperview()
|
||
make.height.equalTo(auto(20))
|
||
make.top.equalTo(destLabel.snp.bottom).offset(auto(10))
|
||
}
|
||
|
||
distanceFromPointLabel.snp.makeConstraints { make in
|
||
make.left.equalTo(orderNumButton)
|
||
make.centerY.equalTo(remainTimeLabel)
|
||
}
|
||
|
||
distanceLabel.snp.makeConstraints { make in
|
||
make.right.equalTo(-auto(20))
|
||
make.centerY.equalTo(remainTimeLabel)
|
||
}
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
func updateData(taskModel: VehicleMonitorListDataModel.TaskModel) {
|
||
orderNumButton.setTitle(taskModel.orderCode, for: .normal)
|
||
titleLabel.text = taskModel.serviceName
|
||
stateLabel.text = taskModel.taskStatusString
|
||
incidentLabel.text = taskModel.vehiclePointAddress
|
||
destLabel.text = taskModel.destinationAddress
|
||
RQ.vehicleMonitorInfo(parameters: VehicleMonitorInfoParameters(vehicleId: taskModel.taskVehicleId,lon: taskModel.lon,lat: taskModel.lat,code: taskModel.orderCode))
|
||
.observe(on: MainScheduler.instance)
|
||
.subscribe(onSuccess: {[weak self] response in
|
||
guard let self = self else { return }
|
||
if let contractName = response?.data?.contractName {
|
||
var contractContent = contractName
|
||
if let organizeName = response?.data?.organizeName {
|
||
contractContent = contractContent + "/" + organizeName
|
||
}
|
||
self.contractContent.text = contractContent
|
||
self.contractTitle.text = "合同:"
|
||
self.contractImageView.image = UIImage(named: "vehichleMonitoring_contract_16")
|
||
}else{
|
||
self.contractContent.text = nil
|
||
self.contractTitle.text = nil
|
||
self.contractImageView.image = nil
|
||
}
|
||
var point : String? = nil
|
||
var leftTime : Int? = nil
|
||
if let leftTimeB = response?.data?.leftTimeB,leftTimeB > 0 {
|
||
point = "B"
|
||
leftTime = Int(leftTimeB)
|
||
}else if let leftTimeC = response?.data?.leftTimeC,leftTimeC > 0 {
|
||
point = "C"
|
||
leftTime = Int(leftTimeC)
|
||
}
|
||
|
||
if let point, let distance = response?.data?.distance {
|
||
let distanceFromPointAttributeString = NSMutableAttributedString(string: "距离\(point)点: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||
distanceFromPointAttributeString.append(NSMutableAttributedString(string: "\(distance)", attributes: [.foregroundColor : UIColor.hex("F93D3D"),.font : UIFont.regularFont(12)]))
|
||
distanceFromPointAttributeString.append(NSMutableAttributedString(string: "km", attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)]))
|
||
self.distanceFromPointLabel.attributedText = distanceFromPointAttributeString
|
||
}
|
||
|
||
let leftTimeAttributeString = NSMutableAttributedString(string: "剩余时间: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||
if let _ = point, let leftTime {
|
||
leftTimeAttributeString.append(NSMutableAttributedString(string: "\(leftTime)", attributes: [.foregroundColor : UIColor.hex("F93D3D"),.font : UIFont.regularFont(12)]))
|
||
leftTimeAttributeString.append(NSMutableAttributedString(string: "分", attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)]))
|
||
self.remainTimeLabel.attributedText = leftTimeAttributeString
|
||
}
|
||
|
||
let bcAttributeString = NSMutableAttributedString(string: "BC: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||
if let mileageBc = response?.data?.mileageBc {
|
||
bcAttributeString.append(NSMutableAttributedString(string: "\(mileageBc)", attributes: [.foregroundColor : UIColor.hex("F93D3D"),.font : UIFont.regularFont(12)]))
|
||
bcAttributeString.append(NSMutableAttributedString(string: "km", attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)]))
|
||
self.distanceLabel.attributedText = bcAttributeString
|
||
}
|
||
|
||
})
|
||
.disposed(by: disposeBag)
|
||
|
||
}
|
||
|
||
func listView() -> UIView! {
|
||
return self
|
||
}
|
||
}
|