Files
OrderScheduling/OrderScheduling/Common/WebView/WebViewTool.swift
T
ddisfriend bf7123d9f0 feat: 充电管理子页面隐藏原生导航栏
- WebViewController 支持按 URL path 列表自动隐藏原生导航栏
- 监听 webView.url 变化,兼容 SPA 路由切换
- 通过 viewSafeAreaInsetsDidChange 动态调整 WebView 顶部约束
- WebViewTool 为充电管理配置需要隐藏导航栏的子页面 path
2026-07-28 17:34:26 +08:00

236 lines
12 KiB
Swift

//
// WebViewTool.swift
// OrderScheduling
//
// Created by 中道 on 2023/8/21.
//
import Foundation
import RxSwift
import RxRelay
public let WEBTOOL = WebViewTool.default
open class WebViewTool : NSObject {
public static let `default` = WebViewTool()
private var requestModelRelay = ReplayRelay<WebViewNameEnum>.create(bufferSize: 1)
private var appendingRelay = ReplayRelay<String?>.create(bufferSize: 1)
private var disposeBag = DisposeBag()
public var h5Models : DispatchAppH5UrlDataModel?
public var bannerInMineDataSources : [ConfigByCodeDataModel.ConfigByCodeBannerModel]?
public var supplierAppIsUserNewReportRelay = ReplayRelay<Any?>.create(bufferSize: 1)
public var supplierAppIsUserNewReport : Bool = false
enum WebViewNameEnum : String {
case todoList = "待办事项"
case workOrderReconciliation = "工单对账"
case vehicleManage = "车辆管理"
case driverManage = "司机管理"
case invoicingNotify = "工单批次"
case roadAndbridgeTollReimbursement = "路桥费报销"
case reporting = " 报备 "
case reportingList = "报备查看"
case supplySettlement = "补结算单"
case workOrderDetail = "工单详情"
case trainDocment = "培训文档"
case docmentDetail = "详情"
case docmentList = "文档资料"
case newTrainingList = "新人培训"
case kpiIndex = "KPI数据统计"
case batteryList = "电瓶进销存"
case invoiceListInfo = "开票信息"
case indexList = "二手车信息"
case insuredPage = "参保救援职业责任险"
case reportIndex = "报备"
case vehicleAlarmDetail = "报警详情"
case vehicleAlarmList = "车辆报警"
case kpiCaseNew = "服务商案件和车辆情况统计"
case managerPeople = "管理人员"
case gjUrl = "充电管理"
}
public override init() {
super.init()
Observable.zip(requestModelRelay, appendingRelay)
.observe(on: MainScheduler.instance)
.do(onNext: {[weak self] (name,appending) in
if let _ = self?.h5Models {
self?.openWebView(name: name,appending: appending)
}else{
let tabBarVc = UIApplication.shared.dd_keyWindow.rootViewController as? UITabBarController
let nav = tabBarVc?.selectedViewController as? UINavigationController
nav?.topViewController?.view.dd_showHUD()
}
})
.filter({[weak self] (name,appending) in
return self?.h5Models == nil
})
.throttle(RxTimeInterval.seconds(20), latest:false, scheduler: ConcurrentMainScheduler.instance)
.flatMapLatest { (name,appending) in
return Observable.zip(RQ.dispatchAppH5Urls().asObservable(), Observable.just(name),Observable.just(appending))
}
.retry(5)
.observe(on: MainScheduler.instance)
.subscribe(onNext: {[weak self] (response,name,appending) in
let tabBarVc = UIApplication.shared.dd_keyWindow.rootViewController as? UITabBarController
let nav = tabBarVc?.selectedViewController as? UINavigationController
nav?.topViewController?.view.dd_hideHUD()
// 仅当有数据才会打开webview,不然提示加载失败
if response?.success == true, let data = response?.data {
self?.h5Models = data
self?.openWebView(name: name,appending: appending)
}else{
nav?.topViewController?.view.dd_makeToast(webViewLoadFailed)
}
})
.disposed(by: disposeBag)
}
private func openWebView(name:WebViewNameEnum,appending:String?) {
var vc : WebViewController?
switch name {
case .todoList:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.todoList.rawValue, url: "\((h5Models?.todoList)!)?token=\((USER.token)!)")
vc?.disappearHandler = {
MCOUNT.newestMessage()
}
break
case .workOrderReconciliation:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.workOrderReconciliation.rawValue, url: "\((h5Models?.workOrderReconciliation)!)?token=\((USER.token)!)")
break
case .vehicleManage:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.vehicleManage.rawValue, url: "\((h5Models?.vehicleManage)!)?token=\((USER.token)!)")
break
case .driverManage:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.driverManage.rawValue, url: "\((h5Models?.driverManage)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .invoicingNotify:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.invoicingNotify.rawValue, url: "\((h5Models?.invoicingNotify)!)?token=\((USER.token)!)")
break
case .roadAndbridgeTollReimbursement:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.invoicingNotify.rawValue, url: "\("\(DOCMENT_HOST)/h5/supplier/dispatch/caseList")?token=\((USER.token)!)")
break
case .reporting:
vc = WebViewController(title: WebViewNameEnum.reporting.rawValue, url: "\((h5Models?.reporting)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .reportingList:
vc = WebViewController(title: WebViewNameEnum.reportingList.rawValue, url: "\((h5Models?.reportingList)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .supplySettlement:
vc = WebViewController(title: WebViewNameEnum.supplySettlement.rawValue, url: "\((h5Models?.supplySettlement)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .workOrderDetail:
vc = WebViewController(title: WebViewNameEnum.workOrderDetail.rawValue, url: "\((h5Models?.workOrderDetail)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .trainDocment:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.trainDocment.rawValue, url: "\((h5Models?.trainDocment)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .docmentDetail:
vc = WebViewController(showNavBar:true, title: WebViewNameEnum.docmentDetail.rawValue, url: "\(DOCMENT_HOST)/res/training/training.html?source=supplierApp"+(appending ?? ""))
break
case .docmentList:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.docmentList.rawValue, url: "\((h5Models?.docmentList)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .newTrainingList:
vc = WebViewController(showNavBar:false, title: WebViewNameEnum.newTrainingList.rawValue, url: "\((h5Models?.newTrainingList)!)?token=\((USER.token)!)"+(appending ?? ""),screenEdgePanGestureRecognizerEnable: false)
break
case .kpiIndex:
vc = WebViewController(showNavBar:true, title: nil, url: "\((h5Models?.kpiIndex)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .batteryList:
vc = WebViewController(showNavBar:false, title: nil, url: "\((h5Models?.batteryList)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .invoiceListInfo:
vc = WebViewController(showNavBar:false, title: nil, url: "\((h5Models?.invoiceListInfo)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .indexList:
vc = WebViewController(showNavBar:false, title: nil, url: "\(bannerInMineDataSourcesLinkUrl(name: .indexList) ?? "")?token=\((USER.token)!)"+(appending ?? ""))
break
case .insuredPage:
vc = WebViewController(showNavBar:false, title: nil, url: "\(bannerInMineDataSourcesLinkUrl(name: .insuredPage) ?? "")?token=\((USER.token)!)"+(appending ?? ""))
break
case .reportIndex:
vc = WebViewController(showNavBar:true, title: WebViewNameEnum.reportIndex.rawValue, url: "\((h5Models?.reportIndex)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .vehicleAlarmList:
vc = WebViewController(showNavBar:true, title: WebViewNameEnum.vehicleAlarmList.rawValue, url: "\((h5Models?.vehicleAlarmList)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .vehicleAlarmDetail:
vc = WebViewController(showNavBar:true, title: WebViewNameEnum.vehicleAlarmDetail.rawValue, url: "\((h5Models?.vehicleAlarmDetail)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .kpiCaseNew:
vc = WebViewController(showNavBar:true, title: nil, url: "\((h5Models?.kpiCaseNew)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .managerPeople:
vc = WebViewController(showNavBar:false, title: nil, url: "\((h5Models?.managerPeople)!)?token=\((USER.token)!)"+(appending ?? ""))
break
case .gjUrl:
vc = WebViewController(showNavBar:true, title: nil, url: "\((h5Models?.gjUrl)!)?"+(appending ?? ""), hiddenNavBarURLPaths: ["/h5/pages/order/list", "/h5/pages/invoice/list"])
break
}
if let vc {
let tabVc = UIApplication.shared.dd_keyWindow.rootViewController as? MainTabBarController
let nav = tabVc?.selectedViewController as? UINavigationController
if let top = nav?.topViewController, top.isMember(of: type(of: vc)) {
return
}
nav?.pushViewController(vc, animated: true)
}
}
func openReportIndex(queryType: Int,userOrderId: Int,orderCode: String,type: Int,userOrderCode: String,supplierId: Int) {
if supplierAppIsUserNewReport == true {
open(name: .reportIndex,appending: "&userOrderId=\(userOrderId)&type=\(type)&userOrderCode=\(userOrderCode)&supplierId=\(supplierId)")
}else{
open(name: .reporting,appending: "&queryType=\(queryType)&userOrderId=\(userOrderId)&orderCode=\(orderCode)")
}
}
func open(name:WebViewNameEnum,appending:String?,completionHandler:(() -> Void)? = nil) {
requestModelRelay.accept(name)
appendingRelay.accept(appending)
}
func bannerInMineDataSourcesContains(name: WebViewNameEnum) -> Bool {
if name == .indexList {
if let source = bannerInMineDataSources?.first(where: { bannerModel in
bannerModel.linkUrl?.contains("indexList") == true
}) {
return true
}
}
if name == .insuredPage {
if let source = bannerInMineDataSources?.first(where: { bannerModel in
bannerModel.linkUrl?.contains("insuredPage") == true
}) {
return true
}
}
return false
}
func bannerInMineDataSourcesLinkUrl(name: WebViewNameEnum) -> String? {
if name == .indexList {
if let source = bannerInMineDataSources?.first(where: { bannerModel in
bannerModel.linkUrl?.contains("indexList") == true
}) {
return source.linkUrl
}
}
if name == .insuredPage {
if let source = bannerInMineDataSources?.first(where: { bannerModel in
bannerModel.linkUrl?.contains("insuredPage") == true
}) {
return source.linkUrl
}
}
return nil
}
}