调度APP车辆在线通报及上线提醒,查看照片部分功能优化,车辆监控页面,新订单提醒
@@ -67,6 +67,7 @@
|
||||
795B949B2BECDB56008F3205 /* NewTraining.swift in Sources */ = {isa = PBXBuildFile; fileRef = 795B949A2BECDB56008F3205 /* NewTraining.swift */; };
|
||||
797484782DA67515003EEB47 /* NewTraningViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797484772DA67515003EEB47 /* NewTraningViewModel.swift */; };
|
||||
79B966382AB0651C00308A8D /* VehicleLogoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79B966372AB0651C00308A8D /* VehicleLogoutView.swift */; };
|
||||
79BF24412E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BF24402E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift */; };
|
||||
79CB07CC2AA8465A00154B61 /* UserPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CB07CB2AA8465A00154B61 /* UserPermission.swift */; };
|
||||
79CECC122A89BD1A00B95D8B /* MessageCenterController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC112A89BD1A00B95D8B /* MessageCenterController.swift */; };
|
||||
79CECC192A89EE6A00B95D8B /* ReviewFailedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC182A89EE6A00B95D8B /* ReviewFailedController.swift */; };
|
||||
@@ -204,6 +205,7 @@
|
||||
795B949A2BECDB56008F3205 /* NewTraining.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTraining.swift; sourceTree = "<group>"; };
|
||||
797484772DA67515003EEB47 /* NewTraningViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTraningViewModel.swift; sourceTree = "<group>"; };
|
||||
79B966372AB0651C00308A8D /* VehicleLogoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleLogoutView.swift; sourceTree = "<group>"; };
|
||||
79BF24402E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlineVehiclesEntryView.swift; sourceTree = "<group>"; };
|
||||
79CB07CB2AA8465A00154B61 /* UserPermission.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPermission.swift; sourceTree = "<group>"; };
|
||||
79CECC112A89BD1A00B95D8B /* MessageCenterController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCenterController.swift; sourceTree = "<group>"; };
|
||||
79CECC182A89EE6A00B95D8B /* ReviewFailedController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewFailedController.swift; sourceTree = "<group>"; };
|
||||
@@ -324,6 +326,7 @@
|
||||
79FB75EF2A98A26C00DB00A4 /* AcceptOrderTool.swift */,
|
||||
792EE0942AA74E0A00A212AB /* PushNotiCommonView.swift */,
|
||||
792EE0962AA74E5800A212AB /* PushNotiCommonTool.swift */,
|
||||
79BF24402E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@@ -1160,6 +1163,7 @@
|
||||
79FB76152A9DEE7400DB00A4 /* RefuseOrderConfirmView.swift in Sources */,
|
||||
79FB76262A9F0A0000DB00A4 /* BackgroundTask.swift in Sources */,
|
||||
79DD0DB12A94B3DB00768FE7 /* EmptyView.swift in Sources */,
|
||||
79BF24412E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift in Sources */,
|
||||
79DD0DAA2A9481BC00768FE7 /* NotificationAuthTool.swift in Sources */,
|
||||
794FBB1C2A8F4DE900D57BB8 /* MessageView.swift in Sources */,
|
||||
794FBB142A8F045F00D57BB8 /* MineController.swift in Sources */,
|
||||
|
||||
23
OrderScheduling/Assets.xcassets/Rescue/online_entry_background.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "online_entry_pin.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "online_entry_pin@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "online_entry_pin@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_background.imageset/online_entry_pin.png
vendored
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_background.imageset/online_entry_pin@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_background.imageset/online_entry_pin@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
23
OrderScheduling/Assets.xcassets/Rescue/online_entry_pin.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "online_entry_background.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "online_entry_background@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "online_entry_background@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_pin.imageset/online_entry_background.png
vendored
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_pin.imageset/online_entry_background@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
OrderScheduling/Assets.xcassets/Rescue/online_entry_pin.imageset/online_entry_background@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "vehichleMonitoring_contract_16.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "vehichleMonitoring_contract_16@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "vehichleMonitoring_contract_16@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 374 B |
|
After Width: | Height: | Size: 603 B |
|
After Width: | Height: | Size: 753 B |
@@ -14,7 +14,7 @@ public let ENTRY = Entry.default
|
||||
open class Entry {
|
||||
public static let `default` = Entry()
|
||||
|
||||
func showLoginNoticeEntry(view:UIView,name:String? = nil) {
|
||||
func showOnlineVehiclesEntry(view:UIView,name:String? = nil) {
|
||||
var attributes = EKAttributes()
|
||||
attributes = .centerFloat
|
||||
attributes.name = name
|
||||
@@ -22,7 +22,7 @@ open class Entry {
|
||||
attributes.displayMode = .inferred
|
||||
attributes.displayDuration = .infinity
|
||||
attributes.screenBackground = .color(color: .clear)
|
||||
attributes.entryBackground = .color(color: .white)
|
||||
attributes.entryBackground = .color(color: .clear)
|
||||
attributes.screenInteraction = .absorbTouches
|
||||
attributes.entryInteraction = .absorbTouches
|
||||
attributes.scroll = .disabled
|
||||
@@ -48,8 +48,8 @@ open class Entry {
|
||||
)
|
||||
)
|
||||
attributes.positionConstraints.size = .init(
|
||||
width: .constant(value: auto(280)),
|
||||
height: .constant(value: auto(130))
|
||||
width: .fill,
|
||||
height: .fill
|
||||
)
|
||||
attributes.positionConstraints.verticalOffset = 0
|
||||
attributes.positionConstraints.safeArea = .overridden
|
||||
|
||||
@@ -132,6 +132,10 @@ open class Tool {
|
||||
}
|
||||
}
|
||||
|
||||
func playVoiceWith(broadcast: String) {
|
||||
DDSS.play(text: broadcast, name: "broadcast")
|
||||
}
|
||||
|
||||
func stopVoice() {
|
||||
DDAS.stopSound(name: "sound")
|
||||
DDSS.stop(name: "broadcast")
|
||||
|
||||
@@ -81,4 +81,8 @@ open class ApiList {
|
||||
public let getAppeal = "/supplierAppV2/dispatchApp/order/getAppeal"
|
||||
|
||||
public let saveAppeal = "/driverApp/task/saveAppeal"
|
||||
|
||||
public let onlineReminder = "/supplierAppV2/dispatchApp/alarm/onlineReminder"
|
||||
|
||||
public let onlineReminderRead = "/supplierAppV2/dispatchApp/alarm/onlineReminderRead"
|
||||
}
|
||||
|
||||
@@ -267,3 +267,11 @@ public struct SaveAppealParameters : Encodable {
|
||||
var vehicleId : Int?
|
||||
var msg : String?
|
||||
}
|
||||
|
||||
public struct OnlineReminderParameters : Encodable {
|
||||
var supplierId : Int?
|
||||
}
|
||||
|
||||
public struct OnlineReminderReadParameters : Encodable {
|
||||
var id : Int?
|
||||
}
|
||||
|
||||
@@ -168,4 +168,12 @@ open class RequestList {
|
||||
func saveAppeal<P:Encodable>(parameters:P) -> Single<ResponseModel<SaveAppealModel>?> {
|
||||
return DDAF.get(urlString: HOST+API.saveAppeal,parameters: parameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<SaveAppealModel>.self)
|
||||
}
|
||||
|
||||
func onlineReminder<P:Encodable>(parameters:P) -> Single<ResponseModel<MessageReminderListDataModel>?> {
|
||||
return DDAF.get(urlString: HOST+API.onlineReminder,parameters: parameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<MessageReminderListDataModel>.self)
|
||||
}
|
||||
|
||||
func onlineReminderRead<P:Encodable>(parameters:P) -> Single<ResponseModel<String>?> {
|
||||
return DDAF.get(urlString: HOST+API.onlineReminderRead,parameters: parameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<String>.self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +185,9 @@ public class VehicleMonitorListDataModel : Decodable {
|
||||
var alarmType : AlarmType?
|
||||
var rosterStartTime : String?
|
||||
var rosterEndTime : String?
|
||||
var rosterType : String?
|
||||
var endTime : String?
|
||||
var startTime : String?
|
||||
var lat : String?
|
||||
var lon : String?
|
||||
var orderCode : String?
|
||||
@@ -229,7 +232,11 @@ public class VehicleMonitorListDataModel : Decodable {
|
||||
var destinationLongitude : Double?
|
||||
var destinationLatitude : Double?
|
||||
var destinationAddress : String?
|
||||
}
|
||||
var leftTimeB : Double?
|
||||
var leftTimeC : Double?
|
||||
var distance : Double?
|
||||
var mileageBc : Double?
|
||||
var contractName : String? }
|
||||
}
|
||||
|
||||
public class OrderPhotoListDataModel : Decodable {
|
||||
|
||||
@@ -20,6 +20,7 @@ open class AcceptOrderTool : NSObject {
|
||||
acceptOrderView.titleLabel.text = "新订单"
|
||||
acceptOrderView.contentLabel.text = TOOL.getOrderString(userInfo: userInfo)
|
||||
acceptOrderView.readButton.setTitle("查看", for: .normal)
|
||||
acceptOrderView.cancelButton.setTitle("稍后查看", for: .normal)
|
||||
acceptOrderView.readButton.rx.tap
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: {
|
||||
|
||||
@@ -18,9 +18,8 @@ open class AcceptOrderView : DDView {
|
||||
public let contentLabel : DDLabel
|
||||
public let horizontalLine : DDView
|
||||
public let verticalLine : DDView
|
||||
public let refuseButton : DDButton
|
||||
public let acceptButton : DDButton
|
||||
public let readButton : DDButton
|
||||
public let cancelButton : DDButton
|
||||
public override init(frame: CGRect) {
|
||||
radiusView = DDView.init()
|
||||
scrollView = DDScrollView()
|
||||
@@ -29,9 +28,8 @@ open class AcceptOrderView : DDView {
|
||||
contentLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(14)), textColor: .hex("203053"))
|
||||
horizontalLine = DDView()
|
||||
verticalLine = DDView()
|
||||
refuseButton = DDButton.dd_initCustom()
|
||||
acceptButton = DDButton.dd_initCustom()
|
||||
readButton = DDButton.dd_initCustom()
|
||||
cancelButton = DDButton.dd_initCustom()
|
||||
super.init(frame: frame)
|
||||
radiusView.layer.cornerRadius = auto(10)
|
||||
radiusView.layer.masksToBounds = true
|
||||
@@ -47,20 +45,14 @@ open class AcceptOrderView : DDView {
|
||||
verticalLine.backgroundColor = .hex("979797").alpha(0.35)
|
||||
verticalLine.isHidden = true
|
||||
radiusView.addSubview(verticalLine)
|
||||
refuseButton.isHidden = true
|
||||
refuseButton.titleLabel?.font = .mediumFont(auto(14))
|
||||
refuseButton.backgroundColor = .white
|
||||
refuseButton.setTitleColor(.black.alpha(0.3), for: .normal)
|
||||
radiusView.addSubview(refuseButton)
|
||||
acceptButton.titleLabel?.font = .mediumFont(auto(14))
|
||||
acceptButton.backgroundColor = .white
|
||||
acceptButton.setTitleColor(.black.alpha(0.3), for: .normal)
|
||||
acceptButton.isHidden = true
|
||||
radiusView.addSubview(acceptButton)
|
||||
readButton.titleLabel?.font = .mediumFont(auto(14))
|
||||
readButton.backgroundColor = .white
|
||||
readButton.setTitleColor(.hex("1D64D2"), for: .normal)
|
||||
radiusView.addSubview(readButton)
|
||||
cancelButton.titleLabel?.font = .mediumFont(auto(14))
|
||||
cancelButton.backgroundColor = .white
|
||||
cancelButton.setTitleColor(.hex("1D64D2"), for: .normal)
|
||||
cancelButton.addSubview(cancelButton)
|
||||
|
||||
radiusView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
@@ -103,23 +95,18 @@ open class AcceptOrderView : DDView {
|
||||
make.width.equalTo(1)
|
||||
}
|
||||
|
||||
refuseButton.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview()
|
||||
make.left.equalToSuperview()
|
||||
make.top.equalTo(horizontalLine.snp.bottom)
|
||||
make.right.equalTo(verticalLine.snp.left)
|
||||
}
|
||||
|
||||
acceptButton.snp.makeConstraints { make in
|
||||
readButton.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview()
|
||||
make.right.equalToSuperview()
|
||||
make.top.equalTo(horizontalLine.snp.bottom)
|
||||
make.left.equalTo(verticalLine.snp.right)
|
||||
}
|
||||
|
||||
readButton.snp.makeConstraints { make in
|
||||
cancelButton.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview()
|
||||
make.left.equalToSuperview()
|
||||
make.top.equalTo(horizontalLine.snp.bottom)
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.right.equalTo(verticalLine.snp.left)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
129
OrderScheduling/Rescue/View/OnlineVehiclesEntryView.swift
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// OnlineVehiclesEntryView.swift
|
||||
// OrderScheduling
|
||||
//
|
||||
// Created by 中道 on 2025/10/13.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
|
||||
/// 弹窗:实时车辆在线情况
|
||||
final class OnlineVehiclesEntryView: UIView {
|
||||
|
||||
// MARK: - Public
|
||||
/// 点击“已知晓”回调
|
||||
var onConfirm: (() -> Void)?
|
||||
|
||||
// MARK: - UI
|
||||
private let pinImageView: UIImageView = {
|
||||
let iv = UIImageView(image: UIImage(named: "online_entry_pin"))
|
||||
iv.contentMode = .scaleAspectFit
|
||||
return iv
|
||||
}()
|
||||
|
||||
private let backgroundImageView: UIImageView = {
|
||||
let iv = UIImageView(image: UIImage(named: "online_entry_background"))
|
||||
iv.contentMode = .scaleAspectFit
|
||||
return iv
|
||||
}()
|
||||
|
||||
private let cardView: UIView = {
|
||||
let v = UIView()
|
||||
v.backgroundColor = .white
|
||||
v.layer.cornerRadius = 16
|
||||
v.layer.shadowColor = UIColor.black.cgColor
|
||||
v.layer.shadowOpacity = 0.12
|
||||
v.layer.shadowRadius = 10
|
||||
v.layer.shadowOffset = CGSize(width: 0, height: 6)
|
||||
return v
|
||||
}()
|
||||
|
||||
private let titleLabel: UILabel = {
|
||||
let l = UILabel()
|
||||
l.text = "实时车辆在线情况"
|
||||
l.textAlignment = .center
|
||||
l.font = .boldSystemFont(ofSize: 16)
|
||||
l.textColor = UIColor(hex: "#040404")
|
||||
return l
|
||||
}()
|
||||
|
||||
/// 富文本正文
|
||||
private let contentLabel: UILabel = {
|
||||
let l = UILabel()
|
||||
l.numberOfLines = 0
|
||||
l.textAlignment = .left
|
||||
l.textColor = UIColor(hex: "#4C5361")
|
||||
l.font = .dd_systemFont(ofSize: 14, weight: .medium)
|
||||
return l
|
||||
}()
|
||||
|
||||
private let confirmButton: UIButton = {
|
||||
let b = UIButton(type: .system)
|
||||
b.setTitle("已知晓", for: .normal)
|
||||
b.setTitleColor(.white, for: .normal)
|
||||
b.titleLabel?.font = .boldSystemFont(ofSize: 16)
|
||||
b.backgroundColor = UIColor(hex: "#3174CE")
|
||||
b.layer.cornerRadius = 24
|
||||
b.layer.masksToBounds = true
|
||||
return b
|
||||
}()
|
||||
|
||||
// MARK: - Init
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
buildUI()
|
||||
}
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
buildUI()
|
||||
}
|
||||
|
||||
convenience init(content: String?) {
|
||||
self.init(frame: .zero)
|
||||
contentLabel.text = content
|
||||
}
|
||||
|
||||
func buildUI() {
|
||||
backgroundColor = .clear
|
||||
|
||||
addSubview(cardView)
|
||||
cardView.addSubview(backgroundImageView)
|
||||
cardView.addSubview(pinImageView)
|
||||
cardView.addSubview(titleLabel)
|
||||
cardView.addSubview(contentLabel)
|
||||
cardView.addSubview(confirmButton)
|
||||
|
||||
cardView.snp.makeConstraints { make in
|
||||
make.centerY.centerX.equalToSuperview()
|
||||
make.left.right.equalToSuperview().inset(30)
|
||||
}
|
||||
|
||||
backgroundImageView.snp.makeConstraints { make in
|
||||
make.left.right.top.equalToSuperview()
|
||||
}
|
||||
|
||||
pinImageView.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.centerY.equalTo(cardView.snp.top)
|
||||
make.size.equalTo(CGSize(width: 88, height: 88))
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(pinImageView.snp.bottom).offset(20)
|
||||
make.left.right.equalTo(cardView).inset(20)
|
||||
}
|
||||
|
||||
contentLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||
make.left.right.equalTo(titleLabel)
|
||||
}
|
||||
|
||||
confirmButton.snp.makeConstraints { make in
|
||||
make.top.equalTo(contentLabel.snp.bottom).offset(18)
|
||||
make.left.right.equalTo(titleLabel)
|
||||
make.height.equalTo(48)
|
||||
make.bottom.equalTo(cardView.snp.bottom).inset(20)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,9 +86,7 @@ extension RescueController {
|
||||
|
||||
USER.refreshTokenSub
|
||||
.subscribe(onNext: {[weak self] _ in
|
||||
NewTraining.default.newTrainingRelay.accept(nil)
|
||||
self?.appBannerRelay.accept(nil)
|
||||
self?.appPushRecordRelay.accept(nil)
|
||||
self?.excuseRelay()
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
@@ -138,19 +136,55 @@ extension RescueController {
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
onlineReminderRelay
|
||||
.flatMapLatest { _ in
|
||||
return RQ.onlineReminder(parameters: OnlineReminderParameters(supplierId: UserData.default.supplierId))
|
||||
}
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak self] response in
|
||||
guard let self = self else { return }
|
||||
|
||||
if response?.success == true, let data = response?.data, let content = data.content {
|
||||
let entryView = OnlineVehiclesEntryView(content: content)
|
||||
entryView.onConfirm = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
RQ.onlineReminderRead(parameters: OnlineReminderReadParameters(id: response?.data?.id))
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onSuccess: {[weak self] readResponse in
|
||||
guard let self = self else { return }
|
||||
if readResponse?.success == true {
|
||||
Entry.default.dismiss(name: "onlineVehiclesEntryView")
|
||||
} else {
|
||||
self.view.dd_makeToast(readResponse?.msg)
|
||||
}
|
||||
})
|
||||
.disposed(by: self.disposeBag)
|
||||
}
|
||||
Entry.default.showOnlineVehiclesEntry(view: entryView, name: "onlineVehiclesEntryView")
|
||||
Tool.default.playVoiceWith(broadcast: content)
|
||||
} else {
|
||||
self.view.dd_makeToast(response?.msg)
|
||||
}
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
// 点击tabBar 需要刷下下列
|
||||
preRefreshRelay
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: {[weak self] _ in
|
||||
NewTraining.default.newTrainingRelay.accept(nil)
|
||||
self?.appBannerRelay.accept(nil)
|
||||
self?.appPushRecordRelay.accept(nil)
|
||||
self?.excuseRelay()
|
||||
MCOUNT.newestMessage()
|
||||
self?.categoryView.reloadData()
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
|
||||
func excuseRelay() {
|
||||
NewTraining.default.newTrainingRelay.accept(nil)
|
||||
appBannerRelay.accept(nil)
|
||||
appPushRecordRelay.accept(nil)
|
||||
onlineReminderRelay.accept(nil)
|
||||
}
|
||||
}
|
||||
|
||||
extension RescueController : TYCyclePagerViewDataSource, TYCyclePagerViewDelegate {
|
||||
@@ -604,7 +638,7 @@ extension RescuePendingOrderController : UITableViewDelegate,UITableViewDataSour
|
||||
cell?.acceptButton.setTitle("接单", for: .normal)
|
||||
cell?.refuseButton.setTitle("拒单", for: .normal)
|
||||
}
|
||||
//
|
||||
//
|
||||
let model = resultArr[indexPath.row]
|
||||
cell?.typeLabel.text = model.taskServiceName
|
||||
cell?.orderNumLabel.text = model.orderCode
|
||||
@@ -1182,6 +1216,8 @@ class RescueController : ZDViewController {
|
||||
private var appBannerRelay = ReplayRelay<Any?>.create(bufferSize: 1)
|
||||
private var bannerDataSources : [ConfigByCodeDataModel.ConfigByCodeBannerModel] = []
|
||||
|
||||
private var onlineReminderRelay = ReplayRelay<Any?>.create(bufferSize: 1)
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
dd_navigationBarBackgroundColor = .hex("354683")
|
||||
|
||||
@@ -12,6 +12,8 @@ import RxSwift
|
||||
import ZLPhotoBrowser
|
||||
import RxCocoa
|
||||
import RxRelay
|
||||
import SnapKit
|
||||
import DDUtilsSwiftKit_Private
|
||||
|
||||
extension AdditionalPhotoController{
|
||||
func addActions() {
|
||||
@@ -79,6 +81,55 @@ extension AdditionalPhotoController{
|
||||
}
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
// 保存至相册(带 HUD,批量保存,统一结果反馈)
|
||||
additionalPhotoView.actionView.save.rx.tap
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
let images = self.collectSelectedImages()
|
||||
guard !images.isEmpty else { self.view.dd_makeToast("请先选择照片"); return }
|
||||
|
||||
// 显示 HUD
|
||||
let hud = ZLProgressHUD.show()
|
||||
|
||||
let group = DispatchGroup()
|
||||
var successCount = 0
|
||||
|
||||
images.forEach { img in
|
||||
group.enter()
|
||||
ZLPhotoManager.saveImageToAlbum(image: img) { isSuccess, _ in
|
||||
if isSuccess { successCount += 1 }
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: .main) {
|
||||
hud.hide()
|
||||
if successCount == images.count {
|
||||
self.view.dd_makeToast("已保存到相册")
|
||||
} else if successCount == 0 {
|
||||
// 全部失败:统一弹窗(沿用库内风格的 alert 方法)
|
||||
self.presentSaveErrorAlert()
|
||||
} else {
|
||||
self.view.dd_makeToast("已保存 \(successCount)/\(images.count) 张")
|
||||
}
|
||||
}
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
// 分享
|
||||
additionalPhotoView.actionView.share.rx.tap
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
let images = self.collectSelectedImages()
|
||||
guard !images.isEmpty else { self.view.dd_makeToast("请先选择照片"); return }
|
||||
let activity = UIActivityViewController(activityItems: images, applicationActivities: nil)
|
||||
activity.modalPresentationStyle = .formSheet
|
||||
self.present(activity, animated: true)
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +178,33 @@ extension AdditionalPhotoController : UICollectionViewDelegate, UICollectionView
|
||||
})
|
||||
.disposed(by: cell!.disposeBag)
|
||||
cell?.takePhotoButton.isHidden = !canModify
|
||||
|
||||
// 选择模式 UI(无图片时不显示选择按钮)
|
||||
let hasImage = (itemModel.photoUrl != nil) || ((cell?.uploadImageView.image) != nil)
|
||||
cell?.selectButton.isHidden = !isSelecting || !hasImage
|
||||
let isChecked = selectedIndexPaths.contains(indexPath)
|
||||
cell?.selectButton.isSelected = isChecked
|
||||
cell?.selectButton.setTitleColor(isChecked ? .white : UIColor.hex("#206FFF"), for: .normal)
|
||||
|
||||
cell?.selectButton.rx.tap
|
||||
.observe(on: MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
// 若当前无图片,忽略点击
|
||||
guard let c = collectionView.cellForItem(at: indexPath) as? AdditionalPhotoCell, c.uploadImageView.isHidden == false else { return }
|
||||
if self.selectedIndexPaths.contains(indexPath) {
|
||||
self.selectedIndexPaths.remove(indexPath)
|
||||
} else {
|
||||
self.selectedIndexPaths.insert(indexPath)
|
||||
}
|
||||
if let c = collectionView.cellForItem(at: indexPath) as? AdditionalPhotoCell {
|
||||
let checked = self.selectedIndexPaths.contains(indexPath)
|
||||
c.selectButton.isSelected = checked
|
||||
c.selectButton.setTitleColor(checked ? .white : UIColor.hex("#206FFF"), for: .normal)
|
||||
}
|
||||
self.updateActionViewVisibility(animated: true)
|
||||
})
|
||||
.disposed(by: cell!.disposeBag)
|
||||
return cell!
|
||||
}
|
||||
|
||||
@@ -138,6 +216,26 @@ extension AdditionalPhotoController : UICollectionViewDelegate, UICollectionView
|
||||
}
|
||||
|
||||
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
if isSelecting {
|
||||
// 无图片的条目不允许选中
|
||||
if let c = collectionView.cellForItem(at: indexPath) as? AdditionalPhotoCell, c.uploadImageView.isHidden {
|
||||
return
|
||||
}
|
||||
if selectedIndexPaths.contains(indexPath) {
|
||||
selectedIndexPaths.remove(indexPath)
|
||||
} else {
|
||||
selectedIndexPaths.insert(indexPath)
|
||||
}
|
||||
if let c = collectionView.cellForItem(at: indexPath) as? AdditionalPhotoCell {
|
||||
let checked = selectedIndexPaths.contains(indexPath)
|
||||
c.selectButton.isSelected = checked
|
||||
c.selectButton.setTitleColor(checked ? .white : UIColor.hex("#206FFF"), for: .normal)
|
||||
}
|
||||
updateActionViewVisibility(animated: true)
|
||||
return
|
||||
}
|
||||
|
||||
// 非选择模式:沿用原预览逻辑
|
||||
let cell = self.collectionView(collectionView, cellForItemAt: indexPath) as? AdditionalPhotoCell
|
||||
if let image = cell?.uploadImageView.image {
|
||||
let vc = ZLImagePreviewController.init(datas: [image as Any],showSelectBtn: false,showBottomView: false)
|
||||
@@ -158,6 +256,9 @@ open class AdditionalPhotoController : ZDViewController {
|
||||
private let taskOrderId : Int
|
||||
private let canModify : Bool
|
||||
private var resultArr : [OrderPhotoListDataModel] = []
|
||||
private var isSelecting = false
|
||||
private var selectedIndexPaths = Set<IndexPath>()
|
||||
private var selectButton: UIButton?
|
||||
public init(userOrderId: Int, orderCode: String, taskOrderId: Int, canModify:Bool){
|
||||
self.userOrderId = userOrderId
|
||||
self.orderCode = orderCode
|
||||
@@ -179,6 +280,14 @@ open class AdditionalPhotoController : ZDViewController {
|
||||
|
||||
addSubviews()
|
||||
addActions()
|
||||
let selectButton = UIButton(type: .system)
|
||||
selectButton.setTitle("选择", for: .normal)
|
||||
selectButton.setTitleColor(.white.alpha(0.7), for: .normal)
|
||||
selectButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
|
||||
selectButton.addTarget(self, action: #selector(toggleSelectMode), for: .touchUpInside)
|
||||
let barButton = UIBarButtonItem(customView: selectButton)
|
||||
navigationItem.rightBarButtonItem = barButton
|
||||
self.selectButton = selectButton
|
||||
}
|
||||
|
||||
func addSubviews() {
|
||||
@@ -194,11 +303,80 @@ open class AdditionalPhotoController : ZDViewController {
|
||||
additionalPhotoView.collectionView.delegate = self
|
||||
additionalPhotoView.collectionView.dataSource = self
|
||||
}
|
||||
|
||||
@objc private func toggleSelectMode() {
|
||||
if isSelecting { cancelSelectMode() } else { enterSelectMode() }
|
||||
}
|
||||
private func enterSelectMode() {
|
||||
isSelecting = true
|
||||
selectedIndexPaths.removeAll()
|
||||
selectButton?.setTitle("取消", for: .normal)
|
||||
updateActionViewVisibility(animated: true)
|
||||
additionalPhotoView.collectionView.reloadData()
|
||||
}
|
||||
private func cancelSelectMode() {
|
||||
isSelecting = false
|
||||
selectedIndexPaths.removeAll()
|
||||
selectButton?.setTitle("选择", for: .normal)
|
||||
updateActionViewVisibility(animated: true)
|
||||
additionalPhotoView.collectionView.reloadData()
|
||||
}
|
||||
private func updateActionViewVisibility(animated: Bool) {
|
||||
let shouldShow = isSelecting && !selectedIndexPaths.isEmpty
|
||||
let targetHeight: CGFloat = shouldShow ? 50 : 0
|
||||
additionalPhotoView.actionView.isHidden = (targetHeight == 0)
|
||||
additionalPhotoView.actionHeightConstraint?.update(offset: targetHeight)
|
||||
if isSelecting {
|
||||
if !selectedIndexPaths.isEmpty {
|
||||
selectButton?.setTitle("取消", for: .normal)
|
||||
} else {
|
||||
selectButton?.setTitle("取消", for: .normal)
|
||||
}
|
||||
} else {
|
||||
selectButton?.setTitle("选择", for: .normal)
|
||||
}
|
||||
if animated {
|
||||
UIView.animate(withDuration: 0.25) { self.view.layoutIfNeeded() }
|
||||
} else {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
private func collectSelectedImages() -> [UIImage] {
|
||||
var images: [UIImage] = []
|
||||
for indexPath in selectedIndexPaths {
|
||||
let sectionModel = resultArr[indexPath.section]
|
||||
let itemModel = sectionModel.photoList[indexPath.item]
|
||||
if let cell = additionalPhotoView.collectionView.cellForItem(at: indexPath) as? AdditionalPhotoCell,
|
||||
let img = cell.uploadImageView.image {
|
||||
images.append(img)
|
||||
} else if let urlString = itemModel.photoUrl,
|
||||
let url = URL(string: urlString),
|
||||
let data = try? Data(contentsOf: url),
|
||||
let img = UIImage(data: data) {
|
||||
images.append(img)
|
||||
}
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
||||
private func presentSaveErrorAlert() {
|
||||
let alert = UIAlertController(title: nil, message: "图片保存失败,请检查相册权限", preferredStyle: .alert)
|
||||
let cancel = UIAlertAction(title: "取消", style: .cancel, handler: nil)
|
||||
let confirm = UIAlertAction(title: "确定", style: .default, handler: { _ in
|
||||
UrlLinks.default.openSetting()
|
||||
})
|
||||
alert.addAction(cancel)
|
||||
alert.addAction(confirm)
|
||||
self.present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open class AdditionalPhotoView : DDView {
|
||||
public var collectionView : DDCollectionView
|
||||
public var actionView : AdditionalPhotoActionView
|
||||
public var actionHeightConstraint : Constraint?
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
let flowLayout = UICollectionViewFlowLayout.init()
|
||||
flowLayout.itemSize = CGSize(width: auto(165), height: auto(100))
|
||||
@@ -207,13 +385,20 @@ open class AdditionalPhotoView : DDView {
|
||||
flowLayout.minimumLineSpacing = auto(10)
|
||||
flowLayout.sectionInset = UIEdgeInsets(top: auto(10), left: auto(15), bottom: auto(10), right: auto(15))
|
||||
collectionView = DDCollectionView(frame: .zero, collectionViewLayout: flowLayout)
|
||||
actionView = AdditionalPhotoActionView()
|
||||
super.init(frame: frame)
|
||||
|
||||
collectionView.backgroundColor = .white
|
||||
addSubview(collectionView)
|
||||
|
||||
collectionView.snp.makeConstraints { make in
|
||||
make.top.left.right.bottom.equalToSuperview()
|
||||
make.top.left.right.equalToSuperview()
|
||||
}
|
||||
actionView.isHidden = true
|
||||
addSubview(actionView)
|
||||
actionView.snp.makeConstraints { make in
|
||||
make.top.equalTo(collectionView.snp.bottom)
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
self.actionHeightConstraint = make.height.equalTo(0).constraint
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +415,7 @@ open class AdditionalPhotoCell : DDCollectionViewCell {
|
||||
public let stateLabel : DDLabel
|
||||
public let takePhotoButton : DDButton
|
||||
public let uploadImageView : DDImageView
|
||||
public let selectButton : DDButton
|
||||
public var disposeBag = DisposeBag()
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@@ -240,8 +426,10 @@ open class AdditionalPhotoCell : DDCollectionViewCell {
|
||||
stateLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .white)
|
||||
takePhotoButton = DDButton.dd_initCustom()
|
||||
uploadImageView = DDImageView.init()
|
||||
selectButton = DDButton.dd_initCustom()
|
||||
super.init(frame: .zero)
|
||||
|
||||
titleLabel.numberOfLines = 2
|
||||
addSubview(titleLabel)
|
||||
backgroundImageView.layer.borderColor = UIColor.hex("000000").alpha(0.1).cgColor
|
||||
backgroundImageView.layer.borderWidth = 0.5
|
||||
@@ -263,8 +451,14 @@ open class AdditionalPhotoCell : DDCollectionViewCell {
|
||||
takePhotoButton.setImage(UIImage(named: "additionalPhotot_takePhoto"), for: .normal)
|
||||
backgroundImageView.addSubview(takePhotoButton)
|
||||
|
||||
backgroundImageView.addSubview(selectButton)
|
||||
selectButton.setImage(UIImage(named: "refuseOrder_reason_unselected"), for: .normal)
|
||||
selectButton.setImage(UIImage(named: "refuseOrder_reason_selected"), for: .selected)
|
||||
selectButton.isHidden = true
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(auto(5))
|
||||
make.right.equalTo(-auto(5))
|
||||
make.top.equalTo(0)
|
||||
}
|
||||
|
||||
@@ -298,6 +492,10 @@ open class AdditionalPhotoCell : DDCollectionViewCell {
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
|
||||
selectButton.snp.makeConstraints { make in
|
||||
make.top.right.equalToSuperview().inset(0)
|
||||
make.width.height.equalTo(auto(30))
|
||||
}
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
@@ -306,6 +504,8 @@ open class AdditionalPhotoCell : DDCollectionViewCell {
|
||||
|
||||
open override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
selectButton.isSelected = false
|
||||
selectButton.isHidden = true
|
||||
disposeBag = DisposeBag()
|
||||
}
|
||||
}
|
||||
@@ -328,3 +528,56 @@ open class AdditionalPhotoHeaderView : DDCollectionViewCell {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
open class AdditionalPhotoActionView : UIView {
|
||||
public let save : UIButton = UIButton(type: .custom)
|
||||
public let share : UIButton = UIButton(type: .custom)
|
||||
private let topSeparator = UIView()
|
||||
private let middleSeparator = UIView()
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
buildUI()
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
buildUI()
|
||||
}
|
||||
|
||||
func buildUI() {
|
||||
// Top horizontal separator
|
||||
topSeparator.backgroundColor = UIColor.hex("E5E6EB")
|
||||
addSubview(topSeparator)
|
||||
topSeparator.snp.makeConstraints { make in
|
||||
make.top.left.right.equalToSuperview()
|
||||
make.height.equalTo(1.0 / UIScreen.main.scale)
|
||||
}
|
||||
|
||||
save.setTitle("保存至相册", for: .normal)
|
||||
save.setTitleColor(.black, for: .normal)
|
||||
save.titleLabel?.font = .dd_systemFont(ofSize: 16, weight: .medium)
|
||||
addSubview(save)
|
||||
share.setTitle("分享", for: .normal)
|
||||
share.setTitleColor(.black, for: .normal)
|
||||
share.titleLabel?.font = .dd_systemFont(ofSize: 16, weight: .medium)
|
||||
addSubview(share)
|
||||
save.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview().multipliedBy(0.5)
|
||||
make.centerY.equalToSuperview()
|
||||
}
|
||||
share.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.centerX.equalToSuperview().multipliedBy(1.5)
|
||||
}
|
||||
|
||||
// Middle vertical separator
|
||||
middleSeparator.backgroundColor = UIColor.hex("E5E6EB")
|
||||
addSubview(middleSeparator)
|
||||
middleSeparator.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.centerY.equalToSuperview()
|
||||
make.width.equalTo(1.0 / UIScreen.main.scale)
|
||||
make.height.equalTo(24)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ import DDUIGestureRecognizer
|
||||
import DDUtilsSwiftKit_Private
|
||||
|
||||
fileprivate let vehicleMonitoringPannelViewHeight = auto(300)
|
||||
fileprivate let vehicleMonitoringPannelCategoryView = auto(40)
|
||||
fileprivate let vehicleMonitoringListDetailViewHeight = auto(190)
|
||||
fileprivate let vehicleMonitoringPannelCategoryViewHeight = auto(40)
|
||||
fileprivate let vehicleMonitoringListDetailViewHeight = auto(270)
|
||||
|
||||
fileprivate let vehicleMonitoringPointAnnotationW = auto(120)
|
||||
fileprivate let vehicleMonitoringPointAnnotationNameLeftInset = auto(35)
|
||||
@@ -768,8 +768,39 @@ extension VehicleMonitoringController {
|
||||
/// 视频按钮显示规则
|
||||
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
|
||||
@@ -959,7 +990,7 @@ open class VehicleMonitoringController : ZDViewController {
|
||||
vehicleMonitoringView.vehicleMonitoringPannelView.categoryView.snp.remakeConstraints { make in
|
||||
make.top.equalToSuperview().priority(.high)
|
||||
make.left.right.equalToSuperview()
|
||||
make.height.equalTo(vehicleMonitoringPannelCategoryView)
|
||||
make.height.equalTo(vehicleMonitoringPannelCategoryViewHeight)
|
||||
}
|
||||
|
||||
vehicleMonitoringListDetailView.layer.cornerRadius = vehicleMonitoringPannelViewCornerRadius
|
||||
@@ -971,13 +1002,13 @@ open class VehicleMonitoringController : ZDViewController {
|
||||
make.bottom.equalToSuperview()
|
||||
})
|
||||
|
||||
let minDisplayHeight = vehicleMonitoringPannelCategoryView
|
||||
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(-vehicleMonitoringPannelCategoryView + vehicleMonitoringPannelViewCornerRadius)
|
||||
make.bottom.equalToSuperview().offset(-vehicleMonitoringPannelCategoryViewHeight + vehicleMonitoringPannelViewCornerRadius)
|
||||
}
|
||||
|
||||
if pannelPanGes.panGesValue.expandLevel == .max {
|
||||
@@ -1355,6 +1386,9 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
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
|
||||
@@ -1380,7 +1414,10 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
settingButton.setBackgroundImage(UIImage(named: "vehicleMonitoring_setting"), for: .normal)
|
||||
videoButton = DDButton.dd_initCustom()
|
||||
videoButton.setBackgroundImage(UIImage(named: "vehicleMonitoring_video_icon"), for: .normal)
|
||||
nameLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(14)), textColor: .hex("11142F"))
|
||||
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()
|
||||
@@ -1404,9 +1441,11 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
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
|
||||
@@ -1427,7 +1466,7 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
|
||||
containerView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(auto(7))
|
||||
make.top.equalTo(backButton.snp.bottom).offset(0)
|
||||
make.top.equalTo(workScheduleContent.snp.bottom).offset(auto(5))
|
||||
make.bottom.equalToSuperview().offset(-auto(10))
|
||||
}
|
||||
|
||||
@@ -1498,6 +1537,11 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
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)
|
||||
@@ -1509,6 +1553,17 @@ class VehicleMonitoringListDetailView : DDView, JXCategoryListContainerViewDeleg
|
||||
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
|
||||
@@ -1572,6 +1627,12 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
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
|
||||
override init(frame: CGRect) {
|
||||
orderNumButton = UIButton()
|
||||
orderNumButton.setTitleColor(.hex("0E76F4"), for: .normal)
|
||||
@@ -1583,6 +1644,12 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
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(image: UIImage(named: "vehichleMonitoring_contract_16"))
|
||||
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()
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(orderNumButton)
|
||||
@@ -1599,6 +1666,14 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
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))
|
||||
@@ -1625,10 +1700,27 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
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(line.snp.bottom).offset(auto(15))
|
||||
make.top.equalTo(contractImageView.snp.bottom).offset(auto(15))
|
||||
}
|
||||
|
||||
incidentLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
@@ -1652,6 +1744,22 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
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) {
|
||||
@@ -1663,7 +1771,38 @@ class VMLDContainerView : DDView , JXCategoryListContentViewDelegate {
|
||||
titleLabel.text = taskModel.serviceName
|
||||
stateLabel.text = taskModel.taskStatusString
|
||||
incidentLabel.text = taskModel.vehiclePointAddress
|
||||
destLabel.text = taskModel.destinationAddress
|
||||
destLabel.text = (taskModel.destinationAddress ?? "") + (taskModel.destinationAddress ?? "")
|
||||
contractContent.text = taskModel.contractName
|
||||
var point = ""
|
||||
var leftTime : Int? = nil
|
||||
if let leftTimeB = taskModel.leftTimeB {
|
||||
point = "B"
|
||||
leftTime = Int(leftTimeB)
|
||||
}else if let leftTimeC = taskModel.leftTimeC {
|
||||
point = "C"
|
||||
leftTime = Int(leftTimeC)
|
||||
}
|
||||
let distanceFromPointAttributeString = NSMutableAttributedString(string: "距离\(point)点: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||||
if let distance = taskModel.distance {
|
||||
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)]))
|
||||
distanceFromPointLabel.attributedText = distanceFromPointAttributeString
|
||||
}
|
||||
|
||||
let leftTimeAttributeString = NSMutableAttributedString(string: "剩余时间: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||||
if 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)]))
|
||||
remainTimeLabel.attributedText = leftTimeAttributeString
|
||||
}
|
||||
|
||||
let bcAttributeString = NSMutableAttributedString(string: "BC: ",attributes: [.foregroundColor : UIColor.hex("11142F"),.font : UIFont.regularFont(12)])
|
||||
if let mileageBc = taskModel.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)]))
|
||||
distanceLabel.attributedText = bcAttributeString
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func listView() -> UIView! {
|
||||
|
||||