From 599077de2de15b484f51d60191b22b108f6b2073 Mon Sep 17 00:00:00 2001 From: ddisfriend Date: Mon, 29 Dec 2025 11:21:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=95=86=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E3=80=81=E8=B0=83=E5=BA=A6APP=E6=96=B0=E5=A2=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=95=86=E4=BA=BA=E5=91=98=E7=A1=AE=E8=AE=A4=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OrderScheduling.xcodeproj/project.pbxproj | 4 + .../mine_info_manage.imageset/Contents.json | 23 +++ .../mine_info_manage.png | Bin 0 -> 402 bytes .../mine_info_manage@2x.png | Bin 0 -> 712 bytes .../mine_info_manage@3x.png | Bin 0 -> 1249 bytes .../Contents.json | 23 +++ .../IdentityAlertNotice.png | Bin 0 -> 1326 bytes .../IdentityAlertNotice@2x.png | Bin 0 -> 3041 bytes .../IdentityAlertNotice@3x.png | Bin 0 -> 5657 bytes .../Common/View/AppUpdateTool.swift | 15 +- .../Common/WebView/WebViewTool.swift | 18 ++ OrderScheduling/Entry/Entry.swift | 54 +++++ .../ViewController/HistoryController.swift | 7 +- .../HttpRequestCenter/ApiList.swift | 8 +- .../HttpRequestCenter/ParametersList.swift | 19 +- .../HttpRequestCenter/RequestList.swift | 16 +- .../HttpResponseModel/ResponseModel.swift | 37 ++-- .../Mine/ViewController/MineController.swift | 104 +++++++--- .../Rescue/View/IdentityAlertView.swift | 186 ++++++++++++++++++ .../ViewController/RescueController.swift | 71 ++++++- 20 files changed, 517 insertions(+), 68 deletions(-) create mode 100644 OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/Contents.json create mode 100644 OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage.png create mode 100644 OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage@2x.png create mode 100644 OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage@3x.png create mode 100644 OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/Contents.json create mode 100644 OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/IdentityAlertNotice.png create mode 100644 OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/IdentityAlertNotice@2x.png create mode 100644 OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/IdentityAlertNotice@3x.png create mode 100644 OrderScheduling/Rescue/View/IdentityAlertView.swift diff --git a/OrderScheduling.xcodeproj/project.pbxproj b/OrderScheduling.xcodeproj/project.pbxproj index f8294b4..0487471 100644 --- a/OrderScheduling.xcodeproj/project.pbxproj +++ b/OrderScheduling.xcodeproj/project.pbxproj @@ -69,6 +69,7 @@ 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 */; }; + 79CE24AA2EF52EAF007FCF90 /* IdentityAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CE24A92EF52EAF007FCF90 /* IdentityAlertView.swift */; }; 79CECC122A89BD1A00B95D8B /* MessageCenterController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC112A89BD1A00B95D8B /* MessageCenterController.swift */; }; 79CECC192A89EE6A00B95D8B /* ReviewFailedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC182A89EE6A00B95D8B /* ReviewFailedController.swift */; }; 79CECC1B2A89F83800B95D8B /* AdditionalPhotoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79CECC1A2A89F83800B95D8B /* AdditionalPhotoController.swift */; }; @@ -207,6 +208,7 @@ 79B966372AB0651C00308A8D /* VehicleLogoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleLogoutView.swift; sourceTree = ""; }; 79BF24402E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlineVehiclesEntryView.swift; sourceTree = ""; }; 79CB07CB2AA8465A00154B61 /* UserPermission.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPermission.swift; sourceTree = ""; }; + 79CE24A92EF52EAF007FCF90 /* IdentityAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityAlertView.swift; sourceTree = ""; }; 79CECC112A89BD1A00B95D8B /* MessageCenterController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCenterController.swift; sourceTree = ""; }; 79CECC182A89EE6A00B95D8B /* ReviewFailedController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewFailedController.swift; sourceTree = ""; }; 79CECC1A2A89F83800B95D8B /* AdditionalPhotoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionalPhotoController.swift; sourceTree = ""; }; @@ -327,6 +329,7 @@ 792EE0942AA74E0A00A212AB /* PushNotiCommonView.swift */, 792EE0962AA74E5800A212AB /* PushNotiCommonTool.swift */, 79BF24402E9CEFB300FA5F1E /* OnlineVehiclesEntryView.swift */, + 79CE24A92EF52EAF007FCF90 /* IdentityAlertView.swift */, ); path = View; sourceTree = ""; @@ -1202,6 +1205,7 @@ 791887AE2A80F943007EA0C1 /* UserData.swift in Sources */, 79FB75EE2A9898EB00DB00A4 /* AcceptOrderView.swift in Sources */, 791887BA2A82495D007EA0C1 /* EnvironmentStrings.swift in Sources */, + 79CE24AA2EF52EAF007FCF90 /* IdentityAlertView.swift in Sources */, 79D964E02E77FE2100309946 /* AppealInputViewController.swift in Sources */, 791887A62A80D50C007EA0C1 /* ParametersList.swift in Sources */, ); diff --git a/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/Contents.json b/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/Contents.json new file mode 100644 index 0000000..873dc6b --- /dev/null +++ b/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "mine_info_manage.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "mine_info_manage@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "mine_info_manage@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage.png b/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage.png new file mode 100644 index 0000000000000000000000000000000000000000..6d5ce7f0e19c4c6d07d4987e002f094ccf1a342d GIT binary patch literal 402 zcmV;D0d4+?P)h#^_^1IIEv&Z6d++E`=*9f7Yd+T)6e@NO#d}bGIEdXWj^j2^G9QTLJT5L+LCFmoV5bGqk`5|w w3$aB@(8RNcog$jJWBc((ZNK*L7Q2+n{07*qoM6N<$f?V^!qyPW_ literal 0 HcmV?d00001 diff --git a/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage@2x.png b/OrderScheduling/Assets.xcassets/Mine/mine_info_manage.imageset/mine_info_manage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d62ae5cb930bfa91931411c2dd08ba9f20d066cf GIT binary patch literal 712 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 bbNSvL{6kaET#lpx{w7@5K2mUVP*UOli_*~2 literal 0 HcmV?d00001 diff --git a/OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/IdentityAlertNotice@2x.png b/OrderScheduling/Assets.xcassets/Rescue/IdentityAlertNotice.imageset/IdentityAlertNotice@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0bfc10419fd401e9cf91146c11f8e121e2961ac9 GIT binary patch literal 3041 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 literal 0 HcmV?d00001 diff --git a/OrderScheduling/Common/View/AppUpdateTool.swift b/OrderScheduling/Common/View/AppUpdateTool.swift index 8b7371a..af55fe4 100644 --- a/OrderScheduling/Common/View/AppUpdateTool.swift +++ b/OrderScheduling/Common/View/AppUpdateTool.swift @@ -61,7 +61,7 @@ open class AppUpdateTool : NSObject { UIApplication.shared.dd_keyWindow.rootViewController?.view.dd_showHUD() }) .flatMapLatest { (type,_) in - return Observable.zip(RQ.versionCheck(parameters: VersionCheckParameters(version: APPINFO.bundleVersionShort())).asObservable(), Observable.just(type)) + return Observable.zip(RQ.updateVersion(parameters: UpdateVersionParameters(appVersion: APPINFO.bundleVersionShort(), supplierId: UserData.default.supplierId)).asObservable(), Observable.just(type)) } .observe(on: MainScheduler.instance) .do(onNext: { (_,_) in @@ -70,18 +70,23 @@ open class AppUpdateTool : NSObject { .observe(on: MainScheduler.instance) .subscribe(onNext: {[weak self] (response,type) in if response?.success == true { - if self?.canUpdate(localVersion: APPINFO.bundleVersionShort(), onlineVersion: response?.data?.appVersion ?? "0") == true { + + if response?.data == nil { + return + } + + if self?.canUpdate(localVersion: APPINFO.bundleVersionShort(), onlineVersion: response?.data?.newAppVersion ?? "0") == true { if type == .auto { - if response?.data?.update.code == .YES || self?.shouldPresentEntry() == true { + if response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue || self?.shouldPresentEntry() == true { if let appUpdateView = self?.appUpdateView { - appUpdateView.isForce(isForce: response?.data?.update.code == .YES ? true : false) + appUpdateView.isForce(isForce: (response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue) ? true : false) appUpdateView.contentLabel.text = response?.data?.description ENTRY.showAppUpdateEntry(view: appUpdateView,name: appUpdateEntry) } } }else if type == .manual { if let appUpdateView = self?.appUpdateView { - appUpdateView.isForce(isForce: response?.data?.update.code == .YES ? true : false) + appUpdateView.isForce(isForce: (response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue) ? true : false) appUpdateView.contentLabel.text = response?.data?.description ENTRY.showAppUpdateEntry(view: appUpdateView,name: appUpdateEntry) } diff --git a/OrderScheduling/Common/WebView/WebViewTool.swift b/OrderScheduling/Common/WebView/WebViewTool.swift index 819a9e6..8851b97 100644 --- a/OrderScheduling/Common/WebView/WebViewTool.swift +++ b/OrderScheduling/Common/WebView/WebViewTool.swift @@ -21,6 +21,8 @@ open class WebViewTool : NSObject { public var h5Models : DispatchAppH5UrlDataModel? public var bannerInMineDataSources : [ConfigByCodeDataModel.ConfigByCodeBannerModel]? + public var supplierAppIsUserNewReportRelay = ReplayRelay.create(bufferSize: 1) + public var supplierAppIsUserNewReport : Bool = false enum WebViewNameEnum : String { case todoList = "待办事项" @@ -45,6 +47,8 @@ open class WebViewTool : NSObject { case reportIndex = "报备" case vehicleAlarmDetail = "报警详情" case vehicleAlarmList = "车辆报警" + case kpiCaseNew = "服务商案件和车辆情况统计" + case managerPeople = "管理人员" } public override init() { @@ -158,6 +162,12 @@ open class WebViewTool : NSObject { 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 } if let vc { @@ -166,6 +176,14 @@ open class WebViewTool : NSObject { 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) diff --git a/OrderScheduling/Entry/Entry.swift b/OrderScheduling/Entry/Entry.swift index 1b9f3b7..e407f5c 100644 --- a/OrderScheduling/Entry/Entry.swift +++ b/OrderScheduling/Entry/Entry.swift @@ -14,6 +14,60 @@ public let ENTRY = Entry.default open class Entry { public static let `default` = Entry() + func showIdentityAlert(view: UIView, name: String? = nil) { + var attributes = EKAttributes.centerFloat + attributes.name = name + attributes.precedence = .override(priority: .min, dropEnqueuedEntries: false) + attributes.displayMode = .inferred + attributes.displayDuration = .infinity + + // ✅ 背景加半透明遮罩 + attributes.screenBackground = .color( + color: EKColor(UIColor.black.withAlphaComponent(0.45)) + ) + + // entry 自己画内容,所以这里透明 + attributes.entryBackground = .color(color: .clear) + + attributes.screenInteraction = .absorbTouches // 必须点按钮才能关闭 + attributes.entryInteraction = .absorbTouches + attributes.scroll = .disabled + + attributes.entranceAnimation = .init( + translate: .init( + duration: 0.25, + spring: .init(damping: 1, initialVelocity: 0) + ) + ) + attributes.exitAnimation = .init( + translate: .init(duration: 0.25) + ) + attributes.popBehavior = .animated( + animation: .init( + translate: .init(duration: 0.25) + ) + ) + attributes.shadow = .active( + with: .init( + color: .black, + opacity: 0.3, + radius: 6 + ) + ) + + // ✅ 让 entry 本身按内容高度来,而不是铺满全屏 + attributes.positionConstraints.size = .init( + width: .offset(value: 40), // 左右各留 20,自己可调 + height: .intrinsic // 高度跟 view 的布局走 + ) + attributes.positionConstraints.verticalOffset = 0 + attributes.positionConstraints.safeArea = .overridden + attributes.positionConstraints.rotation.isEnabled = false + attributes.statusBar = .light + + SwiftEntryKit.display(entry: view, using: attributes) + } + func showOnlineVehiclesEntry(view:UIView,name:String? = nil) { var attributes = EKAttributes() attributes = .centerFloat diff --git a/OrderScheduling/History/ViewController/HistoryController.swift b/OrderScheduling/History/ViewController/HistoryController.swift index 0d46a2e..a446be2 100644 --- a/OrderScheduling/History/ViewController/HistoryController.swift +++ b/OrderScheduling/History/ViewController/HistoryController.swift @@ -241,10 +241,9 @@ extension HistoryItemController : UITableViewDelegate, UITableViewDataSource { cell?.reportButton.rx.tap .observe(on: MainScheduler.instance) .subscribe(onNext: { _ in -// if let supplierId = USER.supplierId { -// WEBTOOL.open(name: .reportIndex,appending: "&userOrderId=\(model.userOrderId)&type=1&userOrderCode=\(model.taskCode)&supplierId=\(supplierId)") -// } - WEBTOOL.open(name: .reporting, appending: "&queryType=\(OrderTypeEnum.UNCLOSED_ORDER.rawValue)&userOrderId=\(model.userOrderId)&orderCode=\(model.orderCode)") + if let supplierId = USER.supplierId { + WEBTOOL.openReportIndex(queryType: OrderTypeEnum.UNCLOSED_ORDER.rawValue, userOrderId: model.userOrderId, orderCode: model.orderCode, type: 1, userOrderCode: model.taskCode, supplierId: supplierId) + } }) .disposed(by: cell!.disposeBag) diff --git a/OrderScheduling/HttpRequestCenter/ApiList.swift b/OrderScheduling/HttpRequestCenter/ApiList.swift index 610978d..96d9b9f 100644 --- a/OrderScheduling/HttpRequestCenter/ApiList.swift +++ b/OrderScheduling/HttpRequestCenter/ApiList.swift @@ -48,9 +48,15 @@ open class ApiList { public let generalInfo = "/supplierAppV2/dispatchApp/user/generalInfo" + public let getNeedConfirmPersonInfo = "/supplierAppV2/dispatchApp/wechat/getNeedConfirmPersonInfo" + + public let giveUp = "/supplierAppV2/dispatchApp/wechat/giveUp" + + public let judgeIfNeedConfirm = "/supplierAppV2/dispatchApp/wechat/judgeIfNeedConfirm" + public let dispatchAppH5Urls = "/supplierAppV2/open/dispatchAppH5Urls" - public let versionCheck = "/supplierAppV2/dispatchApp/user/versionCheck" + public let updateVersion = "/supplierAppV2/dispatchApp/user/updateVersion" public let messageReminderList = "/supplierAppV2/dispatchApp/toDoMessage/messageReminderList" diff --git a/OrderScheduling/HttpRequestCenter/ParametersList.swift b/OrderScheduling/HttpRequestCenter/ParametersList.swift index c4edf2e..4f334d7 100644 --- a/OrderScheduling/HttpRequestCenter/ParametersList.swift +++ b/OrderScheduling/HttpRequestCenter/ParametersList.swift @@ -205,9 +205,10 @@ public struct SupplementOrderPhotoParameters : Encodable { var file : Data } -public struct VersionCheckParameters : Encodable { - var version : String - var platForm : Int = 2 +public struct UpdateVersionParameters : Encodable { + var appVersion : String + var supplierId : Int? + var sysType : String = "ios" } public struct MessageReminderListParameters : Encodable { @@ -278,3 +279,15 @@ public struct VehicleMonitorInfoParameters : Encodable { var lat : String? var code : String? } + +public struct NeedConfirmPersonInfoParameters : Encodable { + var supplierId : Int? +} + +public struct JudgeIfNeedConfirmParameters : Encodable { + var supplierId : Int? +} + +public struct GiveUpParameters : Encodable { + var supplierId : Int? +} diff --git a/OrderScheduling/HttpRequestCenter/RequestList.swift b/OrderScheduling/HttpRequestCenter/RequestList.swift index 0481243..57acbdb 100644 --- a/OrderScheduling/HttpRequestCenter/RequestList.swift +++ b/OrderScheduling/HttpRequestCenter/RequestList.swift @@ -99,12 +99,24 @@ open class RequestList { return DDAF.post(urlString: HOST+API.generalInfo,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) } + func getNeedConfirmPersonInfo(prameters:P) -> Single?> { + return DDAF.get(urlString: HOST+API.getNeedConfirmPersonInfo,parameters: prameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel<[NeedConfirmPersonInfoDataModel]>.self) + } + + func judgeIfNeedConfirm(prameters:P) -> Single?> { + return DDAF.get(urlString: HOST+API.judgeIfNeedConfirm,parameters: prameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) + } + + func giveUp(prameters:P) -> Single?> { + return DDAF.get(urlString: HOST+API.giveUp,parameters: prameters,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) + } + func dispatchAppH5Urls() -> Single?> { return DDAF.post(urlString: HOST+API.dispatchAppH5Urls,encoding: URLEncodedFormParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) } - func versionCheck(parameters:P) -> Single?> { - return DDAF.post(urlString: HOST+API.versionCheck,parameters: parameters,encoding: JSONParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) + func updateVersion(parameters:P) -> Single?> { + return DDAF.post(urlString: HOST+API.updateVersion,parameters: parameters,encoding: JSONParameterEncoder.default,headers: [tokenHeader()],responseType: ResponseModel.self) } func messageReminderList(parameters:P) -> Single?> { diff --git a/OrderScheduling/HttpResponseModel/ResponseModel.swift b/OrderScheduling/HttpResponseModel/ResponseModel.swift index 0e07be4..184c229 100644 --- a/OrderScheduling/HttpResponseModel/ResponseModel.swift +++ b/OrderScheduling/HttpResponseModel/ResponseModel.swift @@ -262,6 +262,15 @@ public class GeneralInfoDataModel : Decodable { var addressLon : Double? } +public class NeedConfirmPersonInfoDataModel : Decodable { +} + +public class JudgeIfNeedConfirmDataModel : Decodable { + var needConfirm : Bool? + var count : Int? + var isLast : Bool? +} + public class DispatchAppH5UrlDataModel : Decodable { var todoList : String? var workOrderReconciliation : String @@ -282,28 +291,17 @@ public class DispatchAppH5UrlDataModel : Decodable { var reportIndex : String var vehicleAlarmList : String var vehicleAlarmDetail : String + var kpiCaseNew : String + var managerPeople : String } -public class VersionCheckDataModel : Decodable { - var id : Int - var appVersion : String - var update : UpdateModel - var appType : TypeModel - class UpdateModel : Decodable { - var code : UpdateEnum - var label : String - } - class TypeModel : Decodable { - var code : Int - var label : String - } - enum UpdateEnum : Int,Decodable { - case NO = 0 - case YES = 1 - } - var updateTime : String? - var createTime : String? +public class UpdateVersionDataModel : Decodable { + var newAppVersion : String? + var update : Int? var description : String? + public enum ForceUpdate : Int { + case force = 1 + } } public class MessageReminderListDataModel : Decodable { @@ -372,6 +370,7 @@ public class AppPushRecordListDataModel : Decodable { public class ConfigByCodeDataModel : Decodable { var bannerConfig : [ConfigByCodeBannerModel]? + var supplierAppIsUserNewReport : String? public class ConfigByCodeBannerModel : Decodable { var linkUrl : String? var bannerIcon : String? diff --git a/OrderScheduling/Mine/ViewController/MineController.swift b/OrderScheduling/Mine/ViewController/MineController.swift index cd95479..ac93e77 100644 --- a/OrderScheduling/Mine/ViewController/MineController.swift +++ b/OrderScheduling/Mine/ViewController/MineController.swift @@ -49,14 +49,14 @@ extension MineController { return RQ.thisWeekNumber() }) .flatMapLatest { numberModel in - return Single.zip(RQ.generalInfo(),Single.just(numberModel)) + return Single.zip(RQ.generalInfo(),RQ.getNeedConfirmPersonInfo(prameters: NeedConfirmPersonInfoParameters(supplierId: UserData.default.supplierId)),Single.just(numberModel)) } .observe(on: MainScheduler.instance) - .subscribe(onNext: {[weak self] response,numberModel in + .subscribe(onNext: {[weak self] response,needConfirmPersonInfoModel,numberModel in + self?.mineView.scrollView.mj_header?.endRefreshing() if response?.success == true { - self?.mineView.scrollView.mj_header?.endRefreshing() self?.mineView.carInfoView.descLabel.text = String(response?.data?.vehicleCount ?? 0)+"台" - self?.mineView.driverInfoView.descLabel.text = String(response?.data?.driverCount ?? 0)+"台" + self?.mineView.driverInfoView.descLabel.text = String(response?.data?.driverCount ?? 0)+"人" if let icon = response?.data?.icon { self?.mineView.avatar.sd_setImage(with: URL(string: icon),placeholderImage: UIImage(named: "placeholder_gender_man")) } @@ -68,6 +68,12 @@ extension MineController { self?.view.dd_makeToast(response?.msg) } + if needConfirmPersonInfoModel?.success == true { + self?.mineView.manageView.descLabel.text = String(needConfirmPersonInfoModel?.data?.count ?? 0)+"人" + }else{ + self?.view.dd_makeToast(response?.msg) + } + if numberModel?.success == true { if let number = numberModel?.data, number > 0 { self?.mineView.ershouche.contentView.isHidden = false @@ -81,6 +87,15 @@ extension MineController { }) .disposed(by: disposeBag) + mineView.manageGes.rx.event + .observe(on: MainScheduler.instance) + .subscribe(onNext: { _ in + if let supplierId = UserData.default.supplierId { + WEBTOOL.open(name: .managerPeople, appending: "&supplierId=\(supplierId)") + } + }) + .disposed(by: disposeBag) + mineView.carInfoGes.rx.event .observe(on: MainScheduler.instance) .subscribe(onNext: { _ in @@ -97,6 +112,13 @@ extension MineController { }) .disposed(by: disposeBag) + mineView.fuwushanganjianGes.rx.event + .observe(on: MainScheduler.instance) + .subscribe(onNext: { _ in + WEBTOOL.open(name: .kpiCaseNew, appending: nil) + }) + .disposed(by: disposeBag) + mineView.shujutongjiGes.rx.event .observe(on: MainScheduler.instance) .subscribe(onNext: { _ in @@ -222,12 +244,15 @@ open class MineController : ZDViewController { make.bottom.equalTo(-view.safeAreaInsets.bottom - CGRectGetHeight(tabBarController?.tabBar.frame ?? .zero)) } + mineView.manageView.titleLabel.text = "管理人员" + mineView.manageView.imageView.image = UIImage(named: "mine_info_manage") mineView.carInfoView.titleLabel.text = "车辆管理" mineView.carInfoView.imageView.image = UIImage(named: "mine_info_car") mineView.driverInfoView.titleLabel.text = "司机管理" mineView.driverInfoView.imageView.image = UIImage(named: "mine_info_driver") - mineView.shujutongji.titleLabel.text = "KPI数据统计" + mineView.fuwushanganjian.titleLabel.text = "服务商案件和车辆情况统计" + mineView.shujutongji.titleLabel.text = "服务商KPI" mineView.gongdanduizhang.titleLabel.text = "工单对账" mineView.gongdanpici.titleLabel.text = "工单批次" mineView.kaipiaoxinxi.titleLabel.text = "开票信息" @@ -326,17 +351,22 @@ open class MineView : DDView { private let topBackgroundImageView : DDImageView public let avatar : DDImageView public let companyLabel : DDLabel + public let manageGes : UITapGestureRecognizer + public let manageView : MineInfoView public let carInfoGes : UITapGestureRecognizer public let carInfoView : MineInfoView public let driverInfoGes : UITapGestureRecognizer public let driverInfoView : MineInfoView public let infoRadiusView : DDView + private let infoStackView: UIStackView public let infoRadiusSeparate : DDImageView public let statisticsRadiusView : DDView public let orderRadiusView : DDView public let materialRadiusView : DDView public let usedCarRadiusView : DDView public let settingsRadiusView : DDView + public let fuwushanganjianGes : UITapGestureRecognizer + public let fuwushanganjian : MineCell public let shujutongjiGes : UITapGestureRecognizer public let shujutongji : MineCell public let gongdanduizhangGes : UITapGestureRecognizer @@ -369,17 +399,22 @@ open class MineView : DDView { topBackgroundImageView = DDImageView() avatar = DDImageView(image: UIImage(named: "placeholder_gender_man")) companyLabel = DDLabel.dd_init(withText: "", font: .mediumFont(auto(12)), textColor: .hex("FFFFFF").alpha(0.5)) + manageView = MineInfoView() + manageGes = UITapGestureRecognizer() carInfoView = MineInfoView() carInfoGes = UITapGestureRecognizer() driverInfoView = MineInfoView() driverInfoGes = UITapGestureRecognizer() infoRadiusView = DDView() + infoStackView = UIStackView() infoRadiusSeparate = DDImageView(image: UIImage(named: "mine_info_separate")) statisticsRadiusView = DDView() orderRadiusView = DDView() materialRadiusView = DDView() usedCarRadiusView = DDView() settingsRadiusView = DDView() + fuwushanganjianGes = UITapGestureRecognizer() + fuwushanganjian = MineCell() shujutongjiGes = UITapGestureRecognizer() shujutongji = MineCell() gongdanduizhangGes = UITapGestureRecognizer() @@ -421,10 +456,20 @@ open class MineView : DDView { infoRadiusView.backgroundColor = .hex("FFFFFF") infoRadiusView.layer.cornerRadius = auto(12) scrollContentView.addSubview(infoRadiusView) + + infoStackView.axis = .horizontal + infoStackView.alignment = .fill + infoStackView.distribution = .fillEqually + infoRadiusView.addSubview(infoStackView) + + manageView.addGestureRecognizer(manageGes) carInfoView.addGestureRecognizer(carInfoGes) - infoRadiusView.addSubview(carInfoView) driverInfoView.addGestureRecognizer(driverInfoGes) - infoRadiusView.addSubview(driverInfoView) + + infoStackView.addArrangedSubview(manageView) + infoStackView.addArrangedSubview(carInfoView) + infoStackView.addArrangedSubview(driverInfoView) + scrollContentView.addSubview(infoRadiusSeparate) statisticsRadiusView.backgroundColor = .hex("FFFFFF") statisticsRadiusView.layer.cornerRadius = auto(6) @@ -441,6 +486,8 @@ open class MineView : DDView { settingsRadiusView.backgroundColor = .hex("FFFFFF") settingsRadiusView.layer.cornerRadius = auto(6) scrollContentView.addSubview(settingsRadiusView) + fuwushanganjian.addGestureRecognizer(fuwushanganjianGes) + statisticsRadiusView.addSubview(fuwushanganjian) shujutongji.addGestureRecognizer(shujutongjiGes) shujutongji.line.isHidden = true statisticsRadiusView.addSubview(shujutongji) @@ -518,14 +565,8 @@ open class MineView : DDView { make.width.equalTo(auto(350)) } - carInfoView.snp.makeConstraints { make in - make.left.top.bottom.equalToSuperview() - make.width.equalToSuperview().multipliedBy(0.5) - } - - driverInfoView.snp.makeConstraints { make in - make.right.top.bottom.equalToSuperview() - make.width.equalToSuperview().multipliedBy(0.5) + infoStackView.snp.makeConstraints { make in + make.edges.equalToSuperview() } infoRadiusSeparate.snp.makeConstraints { make in @@ -537,7 +578,6 @@ open class MineView : DDView { make.top.equalTo(infoRadiusView.snp.bottom).offset(auto(10)) make.width.equalTo(infoRadiusView) make.centerX.equalToSuperview() - make.height.equalTo(auto(55)) } orderRadiusView.snp.makeConstraints { make in @@ -567,11 +607,18 @@ open class MineView : DDView { make.height.equalTo(auto(110)) } - shujutongji.snp.makeConstraints { make in + fuwushanganjian.snp.makeConstraints { make in make.left.right.top.equalToSuperview() make.height.equalTo(auto(55)) } + shujutongji.snp.makeConstraints { make in + make.top.equalTo(fuwushanganjian.snp.bottom) + make.left.right.equalToSuperview() + make.height.equalTo(auto(55)) + make.bottom.equalToSuperview() + } + gongdanduizhang.snp.makeConstraints { make in make.left.right.top.equalToSuperview() make.height.equalTo(auto(55)) @@ -729,23 +776,30 @@ public class MineInfoView : DDView { addSubview(descLabel) addSubview(arrow) + imageView.contentMode = .scaleAspectFit imageView.snp.makeConstraints { make in - make.left.top.equalTo(auto(20)) + make.right.equalTo(titleLabel.snp.left).offset(-auto(5)) + make.width.height.equalTo(auto(24)) + make.centerY.equalTo(titleLabel) } - + titleLabel.snp.makeConstraints { make in - make.left.equalTo(imageView.snp.right).offset(auto(10)) - make.top.equalTo(imageView.snp.top).offset(auto(5)) + make.top.equalToSuperview().offset(auto(10)) + make.bottom.equalTo(snp.centerY).offset(-auto(2.5)) + make.centerX.equalToSuperview().offset(auto(8)) } - + descLabel.snp.makeConstraints { make in make.left.equalTo(titleLabel) - make.top.equalTo(titleLabel.snp.bottom).offset(auto(5)) + make.top.equalTo(snp.centerY).offset(auto(2.5)) + make.bottom.equalToSuperview().offset(-auto(10)) } - + + arrow.contentMode = .scaleAspectFit arrow.snp.makeConstraints { make in - make.right.equalTo(-auto(20)) + make.left.equalTo(titleLabel.snp.right).offset(auto(5)) make.centerY.equalTo(titleLabel) + make.width.height.equalTo(auto(8)) } } diff --git a/OrderScheduling/Rescue/View/IdentityAlertView.swift b/OrderScheduling/Rescue/View/IdentityAlertView.swift new file mode 100644 index 0000000..e7e455f --- /dev/null +++ b/OrderScheduling/Rescue/View/IdentityAlertView.swift @@ -0,0 +1,186 @@ +// +// IdentityAlertView.swift +// OrderScheduling +// +// Created by 中道 on 2025/12/19. +// + +import UIKit +import SnapKit + +final class IdentityAlertView: UIView { + + // MARK: - Public Callbacks + var onConfirm: (() -> Void)? + var onLater: (() -> Void)? + + // MARK: - UI + private let containerView = UIView() + private let iconContainer = UIView() + private let iconImageView = UIImageView() + private let gradientLayer = CAGradientLayer() + private let titleLabel = UILabel() + private let messageLabel = UILabel() + private let confirmButton = UIButton(type: .system) + private let laterButton = UIButton(type: .system) + + // MARK: - Init + + /// times: 第几次提醒;totalTimes: 总次数,比如 3 + init(times: Int = 1, totalTimes: Int = 3, isLast: Bool) { + super.init(frame: .zero) + setupUI(times: times, totalTimes: totalTimes, isLast:isLast) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + gradientLayer.frame = containerView.bounds + } +} + +// MARK: - UI + +private extension IdentityAlertView { + func setupUI(times: Int, totalTimes: Int, isLast: Bool) { + backgroundColor = .clear + + // 容器(白色卡片,顶部有渐变) + addSubview(containerView) + addSubview(iconContainer) + + containerView.layer.cornerRadius = 18 + containerView.layer.masksToBounds = true + + // 渐变背景:上浅橙,下白色,模拟设计稿上半段渐变 + gradientLayer.colors = [ + UIColor(red: 0xFF/255.0, green: 0xE4/255.0, blue: 0xD7/255.0, alpha: 1).cgColor, + UIColor.white.cgColor + ] + gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0) + gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.25) + containerView.layer.insertSublayer(gradientLayer, at: 0) + + // 先约束图标容器:居中,顶在 entry 顶部;宽高 52 + iconContainer.layer.cornerRadius = 26 + iconContainer.layer.masksToBounds = true + iconContainer.backgroundColor = .clear + + iconContainer.snp.makeConstraints { make in + make.top.equalToSuperview() // 让图标顶部贴住 entry 顶部 + make.centerX.equalToSuperview() + make.width.height.equalTo(52) + } + + // 再约束白色卡片:顶部经过图标中心,实现“图标一半悬在卡片外”的效果 + containerView.snp.makeConstraints { make in + make.top.equalTo(iconContainer.snp.centerY) + make.left.right.bottom.equalToSuperview() + } + + // 感叹号图标(切好的 52x52 图片,内含背景样式) + iconImageView.image = UIImage(named: "IdentityAlertNotice") + iconImageView.contentMode = .scaleAspectFit + iconContainer.addSubview(iconImageView) + iconImageView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + // 标题 + titleLabel.text = "重要提示" + titleLabel.font = .boldSystemFont(ofSize: 18) + titleLabel.textColor = UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1) + titleLabel.textAlignment = .center + containerView.addSubview(titleLabel) + + titleLabel.snp.makeConstraints { make in + make.top.equalTo(iconContainer.snp.bottom).offset(16) + make.left.right.equalToSuperview().inset(20) + } + + // 文案 + let reminderText = isLast ? "本次为最后一次提醒" : "此为第\(times)次提醒" + let message = """ + 中道救援将通过您确认的身份及联系方式,向您发送通知。请务必仔细核对您的身份及联系方式等关键信息,以免因无法接收通知而受到损失。\n + \(reminderText),请及时确认。若\(totalTimes)次提醒仍未确认,您将无法承接案件。 + """ + + let attr = NSMutableAttributedString(string: message) + let fullRange = NSRange(location: 0, length: attr.length) + let paragraph = NSMutableParagraphStyle() + paragraph.lineSpacing = 4 + paragraph.alignment = .center + + attr.addAttributes([ + .font: UIFont.systemFont(ofSize: 14), + .foregroundColor: UIColor(red: 0x66/255, green: 0x66/255, blue: 0x66/255, alpha: 1), + .paragraphStyle: paragraph + ], range: fullRange) + + // 高亮 “将无法承接案件。” + if let highlightRange = (message as NSString).range(of: "请务必仔细核对您的身份及联系方式等关键信息").optionalNonEmpty { + attr.addAttribute(.foregroundColor, + value: UIColor(red: 0xF5/255, green: 0x52/255, blue: 0x3C/255, alpha: 1), + range: highlightRange) + } + + messageLabel.attributedText = attr + messageLabel.numberOfLines = 0 + containerView.addSubview(messageLabel) + + messageLabel.snp.makeConstraints { make in + make.top.equalTo(titleLabel.snp.bottom).offset(12) + make.left.right.equalToSuperview().inset(24) + } + + // 立即确认按钮 + confirmButton.setTitle(isLast ? "放弃" : "立即确认", for: .normal) + confirmButton.setTitleColor(.white, for: .normal) + confirmButton.titleLabel?.font = .boldSystemFont(ofSize: 16) + confirmButton.backgroundColor = UIColor(red: 0xFF/255, green: 0x6B/255, blue: 0x50/255, alpha: 1) + confirmButton.layer.cornerRadius = 20 + confirmButton.layer.masksToBounds = true + confirmButton.addTarget(self, action: #selector(handleConfirm), for: .touchUpInside) + containerView.addSubview(confirmButton) + + confirmButton.snp.makeConstraints { make in + make.top.equalTo(messageLabel.snp.bottom).offset(20) + make.left.right.equalToSuperview().inset(40) + make.height.equalTo(40) + } + + // 稍后提醒按钮 + laterButton.setTitle("稍后提醒", for: .normal) + laterButton.setTitleColor(UIColor(red: 0x99/255, green: 0x99/255, blue: 0x99/255, alpha: 1), for: .normal) + laterButton.titleLabel?.font = .systemFont(ofSize: 14) + laterButton.addTarget(self, action: #selector(handleLater), for: .touchUpInside) + containerView.addSubview(laterButton) + + laterButton.snp.makeConstraints { make in + make.top.equalTo(confirmButton.snp.bottom).offset(12) + make.centerX.equalToSuperview() + make.bottom.equalToSuperview().offset(-20) + } + } +} + +// MARK: - Actions + +private extension IdentityAlertView { + @objc func handleConfirm() { + onConfirm?() + } + + @objc func handleLater() { + onLater?() + } +} + +private extension NSRange { + var optionalNonEmpty: NSRange? { + return location != NSNotFound && length > 0 ? self : nil + } +} diff --git a/OrderScheduling/Rescue/ViewController/RescueController.swift b/OrderScheduling/Rescue/ViewController/RescueController.swift index a1aa698..5b36e74 100644 --- a/OrderScheduling/Rescue/ViewController/RescueController.swift +++ b/OrderScheduling/Rescue/ViewController/RescueController.swift @@ -136,6 +136,20 @@ extension RescueController { }) .disposed(by: disposeBag) + WEBTOOL.supplierAppIsUserNewReportRelay + .flatMapLatest { _ in + return RQ.getConfigByCode(parameters: ConfigByCodeParameters(code: "AppIsUseNewReport")) + } + .observe(on: MainScheduler.instance) + .subscribe(onNext: {[weak self] response in + if response?.success == true { + WEBTOOL.supplierAppIsUserNewReport = (response?.data?.supplierAppIsUserNewReport == "true") + }else{ + self?.view.dd_makeToast(response?.msg) + } + }) + .disposed(by: disposeBag) + onlineReminderRelay .flatMapLatest { _ in return RQ.onlineReminder(parameters: OnlineReminderParameters(supplierId: UserData.default.supplierId)) @@ -170,6 +184,43 @@ extension RescueController { }) .disposed(by: disposeBag) + judgeIfNeedConfirmEntryRelay + .flatMapLatest { _ in + return RQ.judgeIfNeedConfirm(prameters: JudgeIfNeedConfirmParameters(supplierId: UserData.default.supplierId)) + } + .observe(on: MainScheduler.instance) + .subscribe(onNext: {[weak self] response in + guard let self = self else { return } + if response?.success == true { + if response?.data?.needConfirm == true { + let isLast = (response?.data?.isLast == true) + let entryName = "IdentityAlert" + let entryView = IdentityAlertView(times: response?.data?.count ?? 0,totalTimes: 3, isLast: isLast) + entryView.onLater = { + Entry.default.dismiss(name: entryName) + } + entryView.onConfirm = { + Entry.default.dismiss(name: entryName,completion: { + if isLast { + RQ.giveUp(prameters: GiveUpParameters(supplierId: UserData.default.supplierId)) + .subscribe(onSuccess: { _ in + }) + .disposed(by: self.disposeBag) + }else{ + if let supplierId = UserData.default.supplierId { + WEBTOOL.open(name: .managerPeople, appending: "&supplierId=\(supplierId)") + } + } + }) + } + Entry.default.showIdentityAlert(view: entryView, name: entryName) + } + }else{ + self.view.dd_makeToast(response?.msg) + } + }) + .disposed(by: disposeBag) + // 点击tabBar 需要刷下下列 preRefreshRelay .observe(on: MainScheduler.instance) @@ -183,9 +234,11 @@ extension RescueController { func excuseRelay() { NewTraining.default.newTrainingRelay.accept(nil) + WEBTOOL.supplierAppIsUserNewReportRelay.accept(nil) appBannerRelay.accept(nil) appPushRecordRelay.accept(nil) onlineReminderRelay.accept(nil) + judgeIfNeedConfirmEntryRelay.accept(nil) } } @@ -937,10 +990,9 @@ extension RescuePendingDispatchController : UITableViewDelegate,UITableViewDataS cell?.reportButton.rx.tap .observe(on: MainScheduler.instance) .subscribe(onNext: { _ in -// if let supplierId = USER.supplierId { -// WEBTOOL.open(name: .reportIndex,appending: "&userOrderId=\(model.userOrderId)&type=1&userOrderCode=\(model.taskCode)&supplierId=\(supplierId)") -// } - WEBTOOL.open(name: .reporting,appending: "&queryType=\(OrderTypeEnum.TO_DISPATCH_VEHICLE.rawValue)&userOrderId=\(model.userOrderId)&orderCode=\(model.orderCode)") + if let supplierId = USER.supplierId { + WEBTOOL.openReportIndex(queryType: OrderTypeEnum.TO_DISPATCH_VEHICLE.rawValue, userOrderId: model.userOrderId, orderCode: model.orderCode, type: 1, userOrderCode: model.taskCode, supplierId: supplierId) + } }) .disposed(by: cell!.disposeBag) cell?.contactButton.rx.tap @@ -1099,10 +1151,9 @@ extension RescueIsIngController : UITableViewDelegate,UITableViewDataSource { cell?.reportButton.rx.tap .observe(on: MainScheduler.instance) .subscribe(onNext: { _ in -// if let supplierId = USER.supplierId { -// WEBTOOL.open(name: .reportIndex,appending: "&userOrderId=\(model.userOrderId)&type=1&userOrderCode=\(model.taskCode)&supplierId=\(supplierId)") -// } - WEBTOOL.open(name: .reporting,appending: "&queryType=\(OrderTypeEnum.TO_DISPATCH_VEHICLE.rawValue)&userOrderId=\(model.userOrderId)&orderCode=\(model.orderCode)") + if let supplierId = USER.supplierId { + WEBTOOL.openReportIndex(queryType: OrderTypeEnum.TO_DISPATCH_VEHICLE.rawValue, userOrderId: model.userOrderId, orderCode: model.orderCode, type: 1, userOrderCode: model.taskCode, supplierId: supplierId) + } }) .disposed(by: cell!.disposeBag) @@ -1221,7 +1272,9 @@ class RescueController : ZDViewController { private var bannerDataSources : [ConfigByCodeDataModel.ConfigByCodeBannerModel] = [] private var onlineReminderRelay = ReplayRelay.create(bufferSize: 1) - + + private var judgeIfNeedConfirmEntryRelay = ReplayRelay.create(bufferSize: 1) + override func viewDidLoad() { super.viewDidLoad() dd_navigationBarBackgroundColor = .hex("354683")