This commit is contained in:
ddisfriend
2025-09-15 17:36:18 +08:00
parent c27999c368
commit f1c64d57f3
7 changed files with 252 additions and 6 deletions

View File

@@ -74,6 +74,7 @@
79CECC222A8A2A2900B95D8B /* VehicleMonitoringController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC212A8A2A2900B95D8B /* VehicleMonitoringController.swift */; };
79CECC242A8B16D400B95D8B /* VehicleMonitoringListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC232A8B16D400B95D8B /* VehicleMonitoringListController.swift */; };
79CECC262A8C749B00B95D8B /* VehicleMonitorVideoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC252A8C749B00B95D8B /* VehicleMonitorVideoController.swift */; };
79D964E02E77FE2100309946 /* AppealInputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79D964DF2E77FE2100309946 /* AppealInputViewController.swift */; };
79DD0DAA2A9481BC00768FE7 /* NotificationAuthTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DD0DA92A9481BC00768FE7 /* NotificationAuthTool.swift */; };
79DD0DB12A94B3DB00768FE7 /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DD0DB02A94B3DB00768FE7 /* EmptyView.swift */; };
79DD0DB42A95F00B00768FE7 /* Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DD0DB32A95F00B00768FE7 /* Extension.swift */; };
@@ -225,6 +226,7 @@
79CECCB52A8E04EF00B95D8B /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
79CECCB62A8E04FA00B95D8B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
79CECCB72A8E050200B95D8B /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
79D964DF2E77FE2100309946 /* AppealInputViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppealInputViewController.swift; sourceTree = "<group>"; };
79DD0DA12A94501500768FE7 /* OrderScheduling-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OrderScheduling-Bridging-Header.h"; sourceTree = "<group>"; };
79DD0DA52A945D9E00768FE7 /* OrderSchedulingRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OrderSchedulingRelease.entitlements; sourceTree = "<group>"; };
79DD0DA62A946B2500768FE7 /* OrderSchedulingDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OrderSchedulingDebug.entitlements; sourceTree = "<group>"; };
@@ -735,6 +737,7 @@
children = (
79CECC182A89EE6A00B95D8B /* ReviewFailedController.swift */,
79CECC1A2A89F83800B95D8B /* AdditionalPhotoController.swift */,
79D964DF2E77FE2100309946 /* AppealInputViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
@@ -1195,6 +1198,7 @@
791887AE2A80F943007EA0C1 /* UserData.swift in Sources */,
79FB75EE2A9898EB00DB00A4 /* AcceptOrderView.swift in Sources */,
791887BA2A82495D007EA0C1 /* EnvironmentStrings.swift in Sources */,
79D964E02E77FE2100309946 /* AppealInputViewController.swift in Sources */,
791887A62A80D50C007EA0C1 /* ParametersList.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@@ -77,4 +77,8 @@ open class ApiList {
public let alarmList = "/supplierAppV2/dispatchApp/alarm/alarmList"
public let getAlarmByCode = "/supplierAppV2/dispatchApp/alarm/getAlarmByCode"
public let getAppeal = "/supplierAppV2/dispatchApp/order/getAppeal"
public let saveAppeal = "/driverApp/task/saveAppeal"
}

View File

@@ -257,3 +257,13 @@ public struct AlarmListParameters : Encodable {
public struct GetAlarmByCodeParameters : Encodable {
var code : String?
}
public struct GetAppealParameters : Encodable {
var orderCode : String?
}
public struct SaveAppealParameters : Encodable {
var orderCode : String?
var vehicleId : Int?
var msg : String?
}

View File

@@ -160,4 +160,12 @@ open class RequestList {
func getAlarmByCode<P:Encodable>(parameters:P) -> Single<ResponseModel<GetAlarmByCodeDataModel>?> {
return DDAF.post(urlString: HOST+API.getAlarmByCode,parameters: parameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<GetAlarmByCodeDataModel>.self)
}
func getAppeal<P:Encodable>(parameters:P) -> Single<ResponseModel<GetAppealDataModel>?> {
return DDAF.get(urlString: HOST+API.getAppeal,parameters: parameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<GetAppealDataModel>.self)
}
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)
}
}

View File

@@ -87,6 +87,8 @@ class OrderListDataModel: Decodable {
var supplierSettleRatio : SupplierSettleRatioModel?
/// 0 1
var schedulingFinalRule : Int?
var showAppealBtn : Bool?
var taskVehicleId : Int?
class SupplierSettleModel : Decodable {
var code : Int
var label : String
@@ -397,3 +399,11 @@ public class GetVideoUrlDataModel : Decodable {
var channelList : [String]?
var realtimeList : [String]?
}
public class GetAppealDataModel : Decodable {
var appealReason : String?
}
public class SaveAppealModel : Decodable {
}

View File

@@ -0,0 +1,75 @@
//
// AppealInputViewController.swift
// OrderScheduling
//
// Created by on 2025/9/15.
//
import UIKit
final class AppealInputViewController: UIViewController {
let titleLabel = UILabel()
let textField = UITextField()
init(prefill: String? = nil) {
super.init(nibName: nil, bundle: nil)
textField.text = prefill
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.layer.cornerRadius = 12
view.clipsToBounds = true
//
titleLabel.text = "申诉理由"
titleLabel.textAlignment = .center
titleLabel.font = .systemFont(ofSize: 16, weight: .semibold)
titleLabel.textColor = .black
//
textField.placeholder = "请输入申诉原因…"
textField.borderStyle = .none
textField.backgroundColor = UIColor(white: 0.98, alpha: 1)
textField.layer.cornerRadius = 10
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.systemBlue.withAlphaComponent(0.35).cgColor
textField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
textField.leftViewMode = .always
textField.clearButtonMode = .whileEditing
textField.returnKeyType = .done
textField.delegate = self
let container = UIStackView(arrangedSubviews: [titleLabel, textField])
container.axis = .vertical
container.spacing = 14
container.alignment = .fill
container.distribution = .fill
view.addSubview(container)
container.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
container.topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
container.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
container.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
container.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16),
textField.heightAnchor.constraint(equalToConstant: 40)
])
}
//
override var preferredContentSize: CGSize {
get { CGSize(width: 280, height: 140) }
set { super.preferredContentSize = newValue }
}
}
extension AppealInputViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}

View File

@@ -14,6 +14,7 @@ import RxRelay
import RxCocoa
import MJRefresh
import ESTabBarController_swift
import PopupDialog
extension ReviewFailedController {
func addActions() {
@@ -196,11 +197,53 @@ extension ReviewFailedController : UITableViewDelegate,UITableViewDataSource {
})
.disposed(by: cell!.disposeBag)
cell!.appealButton.rx.tap
.flatMapLatest({ _ in
return RQ.getAppeal(parameters: GetAppealParameters(orderCode: model.orderCode))
})
.flatMapLatest({ [weak self] response -> Observable<String> in
//
guard response?.data == nil else {
DispatchQueue.main.async {
self?.view.dd_makeToast("该订单正在申诉中")
}
return .empty()
}
//
return Observable<String>.create { ob in
guard let self = self else { return Disposables.create() }
DispatchQueue.main.async {
self.presentAppealPopup(from: self) { reason in
ob.onNext(reason)
ob.onCompleted()
}
}
return Disposables.create()
}
})
.flatMapLatest({ reason in
return RQ.saveAppeal(parameters: SaveAppealParameters(orderCode: model.orderCode, vehicleId: model.taskVehicleId, msg: reason))
})
.observe(on: ConcurrentMainScheduler.instance)
.subscribe(onNext: {[weak self] response in
if response?.success == true {
}else{
self?.view.dd_makeToast(response?.msg)
}
})
.disposed(by: cell!.disposeBag)
if USERP.canSupplierAuditUploadPhotoBtn == true {
cell?.additionalButton.isHidden = false
}else{
cell?.additionalButton.isHidden = true
}
if model.showAppealBtn == true {
cell?.appealButton.isHidden = false
}else{
cell?.appealButton.isHidden = true
}
return cell!
}
@@ -314,6 +357,66 @@ open class ReviewFailedController : ZDViewController {
super.reloadData()
preRefreshRelay.accept(nil)
}
///
/// - Parameters:
/// - from:
/// - prefill:
/// - onConfirm:
func presentAppealPopup(from: UIViewController,
prefill: String? = nil,
onConfirm: @escaping (String) -> Void) {
// VC
let inputVC = AppealInputViewController(prefill: prefill)
//
let popup = PopupDialog(
viewController: inputVC,
buttonAlignment: .horizontal, //
transitionStyle: .bounceDown, //
tapGestureDismissal: false, //
panGestureDismissal: false //
)
//
let cancel = CancelButton(title: "取消") {
// do nothing
}
//
let ok = DefaultButton(title: "确定", dismissOnTap: false) {
let text = inputVC.textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
guard text.isEmpty == false else {
// toast /
inputVC.textField.layer.borderColor = UIColor.systemRed.withAlphaComponent(0.6).cgColor
UIImpactFeedbackGenerator(style: .light).impactOccurred()
return
}
popup.dismiss() {
onConfirm(text)
}
}
popup.addButtons([cancel, ok])
// 线//
let pv = PopupDialogDefaultView.appearance()
pv.titleFont = .systemFont(ofSize: 16, weight: .semibold)
pv.titleTextAlignment = .center
pv.titleColor = .black
pv.messageTextAlignment = .center
let cb = CancelButton.appearance()
cb.titleColor = UIColor.darkText
cb.separatorColor = UIColor.systemGray5
let db = DefaultButton.appearance()
db.titleColor = UIColor.systemBlue
db.separatorColor = UIColor.systemGray5
from.present(popup, animated: true)
}
}
open class ReviewFailedView : DDView {
@@ -343,6 +446,18 @@ open class ReviewFailedCell : DDTableViewCell {
public let orderStatusLabel : DDLabel
public let descLabel : DDLabel
public let dateLabel : DDLabel
public let stackView : UIStackView
public let appealButton : DDButton
public var appealLayer : CAGradientLayer = {
var layer = CAGradientLayer.init()
layer.startPoint = CGPoint(x: 0, y: 0)
layer.endPoint = CGPoint(x: 1, y: 1)
layer.locations = [0.0,1.0]
layer.colors = [UIColor.hex("FF5A2C").cgColor,UIColor.hex("FE9D4D").cgColor]
layer.cornerRadius = auto(4)
layer.masksToBounds = true
return layer
}()
public let additionalButton : DDButton
public var additionalLayer : CAGradientLayer = {
var layer = CAGradientLayer.init()
@@ -364,7 +479,9 @@ open class ReviewFailedCell : DDTableViewCell {
orderStatusLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(12)), textColor: .hex("E69B0B"))
descLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(13)), textColor: .hex("FF8F37"))
dateLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(12)), textColor: .hex("000000").alpha(0.55))
stackView = UIStackView()
additionalButton = DDButton.dd_initCustom()
appealButton = DDButton.dd_initCustom()
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = .hex("F4F5F7")
@@ -385,12 +502,26 @@ open class ReviewFailedCell : DDTableViewCell {
descLabel.numberOfLines = 0
radiusView.addSubview(descLabel)
radiusView.addSubview(dateLabel)
stackView.axis = .horizontal
stackView.distribution = .equalSpacing
stackView.alignment = .center
stackView.spacing = 10
radiusView.addSubview(stackView)
appealButton.setTitle("申诉", for: .normal)
appealButton.setTitleColor(.white, for: .normal)
appealButton.titleLabel?.font = .mediumFont(auto(13))
appealButton.layer.cornerRadius = auto(4)
appealButton.layer.masksToBounds = true
appealButton.contentEdgeInsets = UIEdgeInsets(top: auto(6), left: auto(12), bottom: auto(6), right: auto(12))
stackView.addArrangedSubview(appealButton)
appealButton.layer.insertSublayer(appealLayer, at: 0)
additionalButton.setTitle("补充", for: .normal)
additionalButton.setTitleColor(.white, for: .normal)
additionalButton.titleLabel?.font = .mediumFont(auto(13))
additionalButton.layer.cornerRadius = auto(4)
additionalButton.layer.masksToBounds = true
radiusView.addSubview(additionalButton)
additionalButton.contentEdgeInsets = UIEdgeInsets(top: auto(6), left: auto(12), bottom: auto(6), right: auto(12))
stackView.addArrangedSubview(additionalButton)
additionalButton.layer.insertSublayer(additionalLayer, at: 0)
radiusView.snp.makeConstraints { make in
@@ -432,11 +563,11 @@ open class ReviewFailedCell : DDTableViewCell {
make.bottom.equalTo(-auto(15))
}
additionalButton.snp.makeConstraints { make in
make.right.equalTo(-auto(10))
stackView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-auto(10))
make.centerY.equalTo(dateLabel)
make.width.equalTo(auto(50))
make.height.equalTo(auto(20))
make.height.equalTo(auto(50))
make.left.greaterThanOrEqualTo(dateLabel.snp.right).offset(auto(10))
}
}
@@ -447,10 +578,14 @@ open class ReviewFailedCell : DDTableViewCell {
open override func prepareForReuse() {
super.prepareForReuse()
disposeBag = DisposeBag()
appealButton.isHidden = true
additionalButton.isHidden = true
}
open override func layoutSubviews() {
super.layoutSubviews()
additionalLayer.frame = CGRectMake(0, 0, auto(50), auto(20))
// Match gradient layers to button bounds
appealLayer.frame = appealButton.bounds
additionalLayer.frame = additionalButton.bounds
}
}