// // QSLLoginViewController.swift // QuickSearchLocation // // Created by Destiny on 2024/11/26. // import UIKit import YYText enum QSLLoginJumpType: Int { case mine // 我的 case add // 添加好友 case road // 查看轨迹 case contact // 添加紧急联系人 } class QSLLoginViewController: QSLBaseController { var type: QSLLoginJumpType? lazy var loginBg: UIImageView = { let imageView = UIImageView() imageView.image = UIImage(named: "mine_bg") return imageView }() lazy var backButton: UIButton = { let button = UIButton() button.image(UIImage(named: "public_back_btn")) button.title("登录") button.mediumFont(17) button.textColor(QSLColor.Color_202020) button.setImageTitleLayout(.imgLeft, spacing: 4.rpx) button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside) return button }() lazy var logoImageView: UIImageView = { let imageView = UIImageView() imageView.image = UIImage(named: "mine_about_logo") return imageView }() lazy var phoneView: UIView = { let view = UIView() view.addRadius(radius: 6.rpx) view.backgroundColor = .hexStringColor(hexString: "#FAFAFA") return view }() lazy var phonePreLabel: UILabel = { let label = UILabel() label.text("+86") label.mediumFont(16) label.textColor = QSLColor.Color_202020 return label }() lazy var phoneLineView: UIView = { let view = UIView() view.backgroundColor = .hexStringColor(hexString: "#E2E2E2") return view }() lazy var phoneTextField: UITextField = { let textField = UITextField() textField.maxTextNumber = 11 textField.delegate = self textField.keyboardType = .numberPad textField.textColor = QSLColor.Color_202020 textField.font = UIFont.textF(16) textField.placeholder = "请输入11位手机号码" textField.setPlaceholderAttribute(font: UIFont.textF(16), color: UIColor.hexStringColor(hexString: "#A7A7A7")) return textField }() lazy var codeView: UIView = { let view = UIView() view.addRadius(radius: 6.rpx) view.backgroundColor = .hexStringColor(hexString: "#FAFAFA") return view }() lazy var codeTextField: UITextField = { let textField = UITextField() textField.delegate = self textField.keyboardType = .numberPad textField.textColor = QSLColor.Color_202020 textField.font = UIFont.textF(16) textField.placeholder = "请输入验证码" textField.setPlaceholderAttribute(font: UIFont.textF(16), color: UIColor.hexStringColor(hexString: "#A7A7A7")) return textField }() lazy var codeButton: UIButton = { let button = UIButton() button.addRadius(radius: 4.rpx) button.setBackgroundColor(.hexStringColor(hexString: "#15CBA1", alpha: 0.2), forState: .disabled) button.setBackgroundColor(.hexStringColor(hexString: "#15CBA1", alpha: 1), forState: .normal) button.title("发送验证码") button.textColor(.white) button.font(14) button.addTarget(self, action: #selector(codeButtonAction), for: .touchUpInside) return button }() lazy var selectBtn: UIButton = { let btn = UIButton() btn.image(UIImage(named: "public_select_btn_false"), .normal) btn.image(UIImage(named: "public_select_btn_true"), .selected) btn.addTarget(self, action: #selector(selectButtonAction), for: .touchUpInside) return btn }() lazy var serviceLabel: YYLabel = { let label = YYLabel() let attr = NSMutableAttributedString() let firstAttr = NSMutableAttributedString(string: "已阅读并同意") firstAttr.font(12) firstAttr.color(.hexStringColor(hexString: "#A7A7A7")) attr.append(firstAttr) let blankAttr = NSMutableAttributedString(string: " ") blankAttr.font(12) attr.append(blankAttr) let privacyHL = YYTextHighlight() var privacyStr = "《隐私权政策》" let privacyText = NSMutableAttributedString(string: privacyStr) privacyText.font(12) privacyText.color(.hexStringColor(hexString: "#2F79FF")) privacyText.yy_setTextHighlight(privacyHL, range: NSRange(location: 0, length: privacyStr.count)) privacyHL.tapAction = { [weak self] containerView, text, range, rect in self?.privacyAction() } attr.append(privacyText) attr.append(blankAttr) let andAttr = NSMutableAttributedString(string: "和") andAttr.font(12) andAttr.color(.hexStringColor(hexString: "#A7A7A7")) attr.append(andAttr) attr.append(blankAttr) let serviceHL = YYTextHighlight() var serviceStr = "《用户协议》" let serviceText = NSMutableAttributedString(string: serviceStr) serviceText.font(12) serviceText.color(.hexStringColor(hexString: "#2F79FF")) serviceText.yy_setTextHighlight(serviceHL, range: NSRange(location: 0, length: serviceStr.count)) serviceHL.tapAction = { [weak self] containerView, text, range, rect in self?.serviceAction() } attr.append(serviceText) label.attributedText = attr return label }() lazy var loginBtn: UIButton = { let btn = UIButton() btn.addRadius(radius: 22.rpx) if let image = UIImage.gradient([.hexStringColor(hexString: "#15CBA1", alpha: 0.2), .hexStringColor(hexString: "#1FE0BA", alpha: 0.2)], size: CGSize(width: 280.rpx, height: 44.rpx), locations: [0, 1], direction: .horizontal) { btn.setBackgroundColor(UIColor(patternImage: image), forState: .disabled) } if let image = UIImage.gradient([.hexStringColor(hexString: "#15CBA1"), .hexStringColor(hexString: "#1FE0BA")], size: CGSize(width: 280.rpx, height: 44.rpx), locations: [0, 1], direction: .horizontal) { btn.setBackgroundColor(UIColor(patternImage: image), forState: .normal) } btn.title("登录") btn.textColor(.white) btn.mediumFont(16) btn.addTarget(self, action: #selector(loginButtonAction), for: .touchUpInside) return btn }() override func viewDidLoad() { super.viewDidLoad() initializeView() if let type = self.type { switch type { case .mine: gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1001]) case .add: gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1002]) case .road: gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1003]) case .contact: gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1004]) } } } } extension QSLLoginViewController { @objc func privacyAction() { let vc = QSLWebViewController() vc.webUrl = QSLConfig.AppPrivacyAgreementLink vc.title = "隐私政策" self.navigationController?.pushViewController(vc, animated: true) } @objc func serviceAction() { let vc = QSLWebViewController() vc.webUrl = QSLConfig.AppServiceAgreementLink vc.title = "服务协议" self.navigationController?.pushViewController(vc, animated: true) } @objc func selectButtonAction() { gravityInstance?.track(QSLGravityConst.login_agree) self.selectBtn.isSelected = !self.selectBtn.isSelected } // 验证码 @objc func codeButtonAction() { gravityInstance?.track(QSLGravityConst.login_code) if let phone = self.phoneTextField.text, phone.count == 11 { codeButton.countDown(60) QSLNetwork().request(.userCode(dict: ["phone": phone]), success: { response in }, fail: { code, error in gravityInstance?.track(QSLGravityConst.login_code_fail, properties: ["id": 1001]) self.view.toast(text: "发送失败") }) } else { gravityInstance?.track(QSLGravityConst.login_code_fail, properties: ["id": 1002]) self.view.toast(text: "请输入正确的手机号码") } } // 登录按钮 @objc func loginButtonAction() { gravityInstance?.track(QSLGravityConst.login_click) guard let phone = self.phoneTextField.text, phone.count == 11 else { self.view.toast(text: "请输入正确的手机号码") return } guard let code = self.codeTextField.text else { self.view.toast(text: "请输入验证码") return } if !self.selectBtn.isSelected { gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1001]) self.view.toast(text: "请先阅读并同意《隐私权政策》和《用户协议》") return } QSLLoading.show() QSLNetwork().request(.userLogin(dict: ["phone": phone, "code": code]), success: { response in QSLLoading.hide() let authToken = response.toJSON(modelKey: "data>authToken").stringValue QSLBaseManager.shared.loginUpdateUser(authToken: authToken, phone: phone) UIApplication.keyWindow?.toast(text: "登录成功") gravityInstance?.track(QSLGravityConst.login_success) // 发送通知 NotificationCenter.default.post(name: QSLNotification.QSLLogin, object: nil) // 返回 self.backBtnAction() }, fail: { code, error in if code == 1005 { gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1002]) } else { gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1003]) } QSLLoading.hide() self.view.toast(text: error) }) } } extension QSLLoginViewController: UITextFieldDelegate { } extension QSLLoginViewController { func initializeView() { self.view.backgroundColor = .white self.view.addSubview(loginBg) loginBg.snp.makeConstraints { make in make.left.top.right.equalToSuperview() } self.view.addSubview(backButton) backButton.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 65.rpx, height: 25.rpx)) make.left.equalTo(12.rpx) make.top.equalTo(QSLConst.qsl_kStatusBarFrameH) } self.view.addSubview(logoImageView) logoImageView.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 70.rpx, height: 70.rpx)) make.centerX.equalToSuperview() make.top.equalTo(backButton.snp.bottom).offset(30.rpx) } self.view.addSubview(phoneView) phoneView.addSubview(phonePreLabel) phoneView.addSubview(phoneLineView) phoneView.addSubview(phoneTextField) phoneView.snp.makeConstraints { make in make.left.equalTo(24.rpx) make.right.equalTo(-24.rpx) make.height.equalTo(50.rpx) make.top.equalTo(logoImageView.snp.bottom).offset(40.rpx) } phonePreLabel.snp.makeConstraints { make in make.left.equalTo(12.rpx) make.centerY.equalToSuperview() } phoneLineView.snp.makeConstraints { make in make.top.equalTo(15.rpx) make.bottom.equalTo(-15.rpx) make.left.equalTo(49.rpx) make.width.equalTo(1.rpx) } phoneTextField.snp.makeConstraints { make in make.left.equalTo(phoneLineView.snp.right).offset(25.rpx) make.right.equalTo(-12.rpx) make.top.bottom.equalTo(0) } self.view.addSubview(codeView) codeView.addSubview(codeTextField) codeView.addSubview(codeButton) codeView.snp.makeConstraints { make in make.left.equalTo(24.rpx) make.right.equalTo(-24.rpx) make.height.equalTo(50.rpx) make.top.equalTo(phoneView.snp.bottom).offset(12.rpx) } codeButton.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 90.rpx, height: 32.rpx)) make.right.equalTo(-12.rpx) make.centerY.equalToSuperview() } codeTextField.snp.makeConstraints { make in make.left.equalTo(12.rpx) make.top.bottom.equalTo(0) make.right.equalTo(codeButton.snp.left).offset(-12.rpx) } self.view.addSubview(selectBtn) self.view.addSubview(serviceLabel) selectBtn.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 12.rpx, height: 12.rpx)) make.left.equalTo(25.rpx) make.top.equalTo(codeView.snp.bottom).offset(14.rpx) } serviceLabel.snp.makeConstraints { make in make.centerY.equalTo(selectBtn.snp.centerY) make.left.equalTo(selectBtn.snp.right).offset(4.rpx) } self.view.addSubview(loginBtn) loginBtn.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 280.rpx, height: 44.rpx)) make.centerX.equalToSuperview() make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom - 95.rpx) } } }