365 lines
16 KiB
Swift
365 lines
16 KiB
Swift
//
|
|
// LoginController.swift
|
|
// OrderScheduling
|
|
//
|
|
// Created by 中道 on 2023/8/4.
|
|
//
|
|
|
|
import Foundation
|
|
import SnapKit
|
|
import RxRelay
|
|
import RxCocoa
|
|
import RxSwift
|
|
import DDTimerSwiftKit_Private
|
|
import DDProgressHUDKit_Private
|
|
import DDAutoUIKit_Private
|
|
import DDControlsKit_Private
|
|
import DDUtilsSwiftKit_Private
|
|
import SwiftyRSA
|
|
|
|
class LoginController : ZDViewController {
|
|
private let disposeBag = DisposeBag()
|
|
private let loginView = LoginView.init()
|
|
private let loginNoticeView = CommonAlertView()
|
|
private let agreeSub = ReplaySubject<Bool>.create(bufferSize: 1)
|
|
private let loginSub = ReplaySubject<Bool>.create(bufferSize: 1)
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
dd_navigationBarBackgroundColor = .clear
|
|
navigationItem.leftBarButtonItems = nil
|
|
addSubviews()
|
|
addActions()
|
|
}
|
|
}
|
|
extension LoginController {
|
|
func addSubviews() {
|
|
view.addSubview(loginView)
|
|
loginView.snp.makeConstraints { make in
|
|
make.edges.equalToSuperview()
|
|
}
|
|
|
|
loginView.backgroundImageView.image = UIImage(named: "login_backgroundImage")
|
|
loginView.inputContentView.backgroundColor = UIColor.white
|
|
loginView.phoneView.titleLabel.text = "用户名"
|
|
loginView.phoneView.textfield.attributedPlaceholder = NSAttributedString(string: "请输入用户名",attributes: [.foregroundColor: UIColor.hex("203152").alpha(0.2),.font:UIFont.regularFont(auto(14))])
|
|
loginView.phoneView.textfield.text = USER.phone
|
|
loginView.codeView.titleLabel.text = "密码"
|
|
loginView.codeView.textfield.attributedPlaceholder = NSAttributedString(string: "请输入密码",attributes: [.foregroundColor: UIColor.hex("203152").alpha(0.2),.font:UIFont.regularFont(auto(14))])
|
|
loginView.codeView.textfield.isSecureTextEntry = true
|
|
loginView.codeView.eyeButton.isHidden = false
|
|
loginView.codeView.eyeButton.adjustsImageWhenHighlighted = false
|
|
loginView.codeView.eyeButton.setImage(UIImage(named: "login_eye_close")?.withTintColor(.lightGray), for: .normal)
|
|
loginView.codeView.eyeButton.setImage(UIImage(named: "login_eye_open")?.withTintColor(.lightGray), for: .selected)
|
|
loginView.agreeButton.setBackgroundImage(UIImage(named: "login_agree_unselected"), for: .normal)
|
|
loginView.agreeButton.setBackgroundImage(UIImage(named: "login_agree_selected"), for: .selected)
|
|
let privacyText = NSAttributedString.init(string: "已阅读并同意",attributes: [.foregroundColor:UIColor.hex("203152"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
|
|
let privacyText_appendUser = NSAttributedString.init(string: "《用户协议》",attributes: [.foregroundColor:UIColor.hex("354D93"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
|
|
privacyText_appendUser.addAttribute(.link, value: login_attach_userAgreement_key, range: NSRange(location: 0, length: privacyText_appendUser.length))
|
|
let privacyText_appendPrivacy = NSAttributedString.init(string: "《隐私协议》",attributes: [.foregroundColor:UIColor.hex("354D93"),.font:UIFont.regularFont(auto(14))]).dd_mutable()
|
|
privacyText_appendPrivacy.addAttribute(.link, value: login_attach_privacy_key, range: NSRange(location: 0, length: privacyText_appendPrivacy.length))
|
|
loginView.agreeTextView.attributedText = privacyText.dd_append(privacyText_appendUser).dd_append(privacyText_appendPrivacy)
|
|
loginView.agreeTextView.textContainerInset = .zero
|
|
loginView.agreeTextView.textContainer.lineFragmentPadding = 0
|
|
loginView.agreeTextView.isEditable = false
|
|
loginView.agreeTextView.delegate = self
|
|
|
|
loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(0.4)
|
|
loginView.loginButton.setTitle("登录", for: .normal)
|
|
|
|
loginNoticeView.sureButton.setTitle("登录", for: .normal)
|
|
}
|
|
}
|
|
extension LoginController {
|
|
func addActions() {
|
|
loginView.codeView.eyeButton.rx.tap
|
|
.observe(on: MainScheduler.instance)
|
|
.subscribe(onNext: {[weak self] in
|
|
if let isSelected = self?.loginView.codeView.eyeButton.isSelected {
|
|
self?.loginView.codeView.eyeButton.isSelected = !isSelected
|
|
self?.loginView.codeView.textfield.isSecureTextEntry = isSelected
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
loginView.agreeButton.rx.tap
|
|
.asDriver()
|
|
.drive(onNext: {[weak self] _ in
|
|
if let isSelected = self?.loginView.agreeButton.isSelected {
|
|
self?.agreeButtonBinder.onNext(!isSelected)
|
|
self?.agreeSub.onNext(!isSelected)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
Observable.combineLatest(loginView.phoneView.textfield.rx.text, loginView.codeView.textfield.rx.text,agreeSub)
|
|
.asDriver(onErrorJustReturn: ("","",false))
|
|
.drive(onNext: {[weak self] (phone,code,isAgree) in
|
|
if phone?.isEmpty == false && code?.isEmpty == false && isAgree == true {
|
|
self?.loginView.loginButton.isEnabled = true
|
|
self?.loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(1)
|
|
}else{
|
|
self?.loginView.loginButton.isEnabled = false
|
|
self?.loginView.loginButton.backgroundColor = .hex("1C6CCE").alpha(0.4)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
loginView.loginButton.rx.tap
|
|
.observe(on: MainScheduler.instance)
|
|
.do(onNext: {[weak self] _ in
|
|
self?.view.dd_showHUD()
|
|
})
|
|
.map({[weak self] _ in
|
|
CheckLoginParameters(username: self?.loginView.phoneView.textfield.text ?? "", deviceId: USER.deviceId ?? "")
|
|
})
|
|
.flatMapLatest({ checkLoginParameters in
|
|
return RQ.checkLogin(parameters: checkLoginParameters)
|
|
})
|
|
.observe(on: MainScheduler.instance)
|
|
.do(onNext: {[weak self] _ in
|
|
self?.view.dd_hideHUD()
|
|
})
|
|
.observe(on: MainScheduler.instance)
|
|
.subscribe(onNext: {[weak self] response in
|
|
if response?.code == 200 {
|
|
self?.loginSub.onNext(true)
|
|
}else{
|
|
self?.view.dd_makeToast(response?.msg)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
loginNoticeView.sureButton.rx.tap
|
|
.observe(on: MainScheduler.instance)
|
|
.subscribe(onNext: {[weak self] in
|
|
ENTRY.dismiss(name: loginNoticeEntry) {[weak self] in
|
|
self?.loginSub.onNext(true)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
loginNoticeView.cancelButton.rx.tap
|
|
.observe(on: MainScheduler.instance)
|
|
.subscribe(onNext: {
|
|
ENTRY.dismiss(name: loginNoticeEntry) {
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
loginSub
|
|
.observe(on: MainScheduler.instance)
|
|
.do(onNext: {[weak self] _ in
|
|
self?.view.dd_showHUD()
|
|
})
|
|
.map({[weak self] _ in
|
|
let username = self?.loginView.phoneView.textfield.text ?? ""
|
|
let clientType = "rescueApp"
|
|
let appVsersion = APPINFO.bundleVersionShort()
|
|
let brand = "iPhone"
|
|
let model = DEVICEINFO.deviceModel()
|
|
let sdkRelease = UIDevice.current.systemVersion
|
|
let platform = "iOS"
|
|
let deviceId = USER.deviceId ?? ""
|
|
let regId = USER.regId ?? ""
|
|
|
|
let timeInterval = Int(Date().timeIntervalSince1970)
|
|
|
|
let publicKey = try PublicKey(pemEncoded: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDf05hs909mzFcBmZez2HfiElirxm89cJVmPIB6x63EnErH1gDpEDwkTIA9iNPBx7b9TwraGIktZ/+qQK17aRrHuD9Bd2KoJaZ1+p3slilEP53ub+I/bd/klDYGgXWooxJ4N8H8MBk/xKgB3MLqVMPf54G9hBtfetodWGYSPr/TrwIDAQAB")
|
|
|
|
let pwd = self?.loginView.codeView.textfield.text ?? ""
|
|
let pwdStr = "rescueApp${\(pwd)}${\(timeInterval)}"
|
|
let clear = try? ClearMessage(string: pwdStr, using: .utf8)
|
|
let encrypted = try? clear?.encrypted(with: publicKey, padding: .PKCS1)
|
|
let base64String = encrypted?.base64String ?? ""
|
|
|
|
let str = "{\"username\":\"\(username)\",\"password\":\"\(base64String)\",\"timestamp\":\"\(timeInterval)\",\"clientType\":\"\(clientType)\",\"appVersion\":\"\(appVsersion)\",\"brand\":\"\(brand)\",\"model\":\"\(model)\",\"sdkRelease\":\"\(sdkRelease)\",\"platform\":\"\(platform)\",\"deviceId\":\"\(deviceId)\",\"regId\":\"\(regId)\"}"
|
|
return str
|
|
})
|
|
.flatMapLatest({ app_login_json in
|
|
return RQ.login(parameters: LoginParameters(app_login_json: app_login_json, client_id: true))
|
|
})
|
|
.observe(on: MainScheduler.instance)
|
|
.do(onNext: {[weak self] _ in
|
|
self?.view.dd_hideHUD()
|
|
})
|
|
.subscribe(onNext: {[weak self] responseModel in
|
|
if responseModel?.success == true {
|
|
if let token = responseModel?.data?.accessToken.tokenValue {
|
|
USER.setToken(token: token)
|
|
USER.setRefreshToken(token: responseModel?.data?.refreshToken.tokenValue)
|
|
USER.setSupplierType(supplierType: responseModel?.data?.additionalParameters.user_info?.supplierType)
|
|
USER.setPhone(phone: self?.loginView.phoneView.textfield.text)
|
|
USER.setSupplierName(supplierName: responseModel?.data?.additionalParameters.user_info?.supplierName)
|
|
USER.setUserId(userId: responseModel?.data?.additionalParameters.user_info?.userId)
|
|
USER.setSupplierId(supplierId: responseModel?.data?.additionalParameters.user_info?.supplierId)
|
|
}
|
|
NotificationCenter.default.post(name: NSNotification.Name(rawValue: Notification_loginSuccessToRescueController), object: nil)
|
|
}else{
|
|
print("错误")
|
|
self?.view.dd_makeToast(responseModel?.msg)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
}
|
|
}
|
|
|
|
extension LoginController {
|
|
var agreeButtonBinder : Binder<Bool> {
|
|
return Binder(loginView.agreeButton) { agreeButton, isSelected in
|
|
agreeButton.isSelected = isSelected
|
|
}
|
|
}
|
|
}
|
|
|
|
extension LoginController : UITextViewDelegate {
|
|
public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
|
|
if URL.absoluteString == login_attach_userAgreement_key {
|
|
// let vc = WebViewController.init(title: "用户协议",url: "")
|
|
// navigationController?.pushViewController(vc, animated: true)
|
|
}
|
|
if URL.absoluteString == login_attach_privacy_key {
|
|
// let vc = WebViewController.init(title: "隐私协议",url: "")
|
|
// navigationController?.pushViewController(vc, animated: true)
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
class LoginView : DDView {
|
|
public let backgroundImageView : DDImageView
|
|
public let inputContentView : DDView
|
|
public let phoneView : LoginInputView
|
|
public let codeView : LoginInputView
|
|
public let agreeButton : DDButton
|
|
public let agreeTextView : DDTextView
|
|
public let loginButton : DDButton
|
|
override init(frame: CGRect) {
|
|
backgroundImageView = DDImageView.init()
|
|
inputContentView = DDView.init()
|
|
phoneView = LoginInputView.init()
|
|
codeView = LoginInputView.init()
|
|
agreeButton = DDButton.init()
|
|
agreeTextView = DDTextView.init()
|
|
loginButton = DDButton.dd_initCustom()
|
|
super.init(frame: frame)
|
|
|
|
addSubview(backgroundImageView)
|
|
inputContentView.layer.shadowColor = UIColor.black.alpha(0.3).cgColor
|
|
inputContentView.layer.shadowRadius = 5
|
|
inputContentView.layer.shadowOffset = CGSize(width: 0, height: 0)
|
|
inputContentView.layer.shadowOpacity = 1
|
|
addSubview(inputContentView)
|
|
phoneView.textfield.keyboardType = .default
|
|
inputContentView.addSubview(phoneView)
|
|
codeView.textfield.keyboardType = .default
|
|
inputContentView.addSubview(codeView)
|
|
agreeButton.contentMode = .scaleAspectFill
|
|
inputContentView.addSubview(agreeButton)
|
|
agreeTextView.isSelectable = false
|
|
inputContentView.addSubview(agreeTextView)
|
|
loginButton.isEnabled = false
|
|
addSubview(loginButton)
|
|
|
|
backgroundImageView.snp.makeConstraints { make in
|
|
make.top.left.right.equalToSuperview()
|
|
make.height.equalTo(auto(423))
|
|
}
|
|
|
|
inputContentView.layer.cornerRadius = auto(10)
|
|
inputContentView.snp.makeConstraints { make in
|
|
make.centerX.equalToSuperview()
|
|
make.top.equalTo(backgroundImageView.snp.bottom).offset(-auto(180))
|
|
make.height.equalTo(auto(205))
|
|
make.width.equalTo(auto(340))
|
|
}
|
|
|
|
phoneView.snp.makeConstraints { make in
|
|
make.left.right.equalToSuperview()
|
|
make.top.equalToSuperview()
|
|
make.height.equalTo(auto(75))
|
|
}
|
|
|
|
codeView.snp.makeConstraints { make in
|
|
make.left.right.equalToSuperview()
|
|
make.top.equalTo(phoneView.snp.bottom)
|
|
make.height.equalTo(phoneView)
|
|
}
|
|
|
|
agreeButton.snp.makeConstraints { make in
|
|
make.top.equalTo(codeView.snp.bottom).offset(auto(20))
|
|
make.left.equalTo(auto(20))
|
|
}
|
|
|
|
agreeTextView.snp.makeConstraints { make in
|
|
make.centerY.equalTo(agreeButton)
|
|
make.left.equalTo(agreeButton.snp.right).offset(auto(5))
|
|
make.right.equalToSuperview()
|
|
make.height.equalTo(18)
|
|
}
|
|
|
|
loginButton.layer.cornerRadius = auto(25)
|
|
loginButton.snp.makeConstraints { make in
|
|
make.top.equalTo(inputContentView.snp.bottom).offset(auto(30))
|
|
make.width.equalTo(auto(300))
|
|
make.height.equalTo(auto(50))
|
|
make.centerX.equalToSuperview()
|
|
}
|
|
}
|
|
|
|
required public init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
}
|
|
|
|
class LoginInputView : DDView {
|
|
public let titleLabel : DDLabel
|
|
public let textfield : DDTextField
|
|
public let eyeButton : DDButton
|
|
public let line : DDView
|
|
override init(frame: CGRect) {
|
|
titleLabel = DDLabel.dd_init(withText: "", font: .regularFont(auto(15)), textColor: .hex("203152"))
|
|
textfield = DDTextField.init()
|
|
eyeButton = DDButton.dd_initCustom()
|
|
line = DDView.init()
|
|
line.backgroundColor = .hex("F1F2F5")
|
|
super.init(frame: frame)
|
|
|
|
addSubview(titleLabel)
|
|
addSubview(textfield)
|
|
eyeButton.isHidden = true
|
|
addSubview(eyeButton)
|
|
addSubview(line)
|
|
|
|
line.snp.makeConstraints { make in
|
|
make.bottom.equalToSuperview()
|
|
make.left.equalTo(auto(20))
|
|
make.right.equalTo(-auto(20))
|
|
make.height.equalTo(1)
|
|
}
|
|
|
|
titleLabel.snp.makeConstraints { make in
|
|
make.left.equalTo(line)
|
|
make.top.equalTo(auto(25))
|
|
}
|
|
|
|
textfield.snp.makeConstraints { make in
|
|
make.left.equalTo(titleLabel)
|
|
make.bottom.equalTo(line.snp.top).offset(-auto(5))
|
|
make.left.equalTo(line)
|
|
make.right.equalTo(eyeButton.snp.left).offset(-auto(5))
|
|
}
|
|
|
|
eyeButton.snp.makeConstraints { make in
|
|
make.right.equalToSuperview().offset(-auto(10))
|
|
make.centerY.equalTo(textfield)
|
|
make.width.equalTo(auto(48))
|
|
}
|
|
}
|
|
|
|
required public init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
}
|