Files
OrderScheduling/OrderScheduling/Login/ViewController/LoginController.swift
2023-10-12 17:02:14 +08:00

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")
}
}