QSLLoginViewController.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. //
  2. // QSLLoginViewController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2024/11/26.
  6. //
  7. import UIKit
  8. import YYText
  9. enum QSLLoginJumpType: Int {
  10. case mine // 我的
  11. case add // 添加好友
  12. case road // 查看轨迹
  13. case contact // 添加紧急联系人
  14. case onQucikLogin // 意见登录
  15. case member // 会员页
  16. }
  17. class QSLLoginViewController: QSLBaseController {
  18. var type: QSLLoginJumpType?
  19. lazy var loginBg: UIImageView = {
  20. let imageView = UIImageView()
  21. imageView.image = UIImage(named: "mine_bg")
  22. return imageView
  23. }()
  24. lazy var backButton: UIButton = {
  25. let button = UIButton()
  26. button.image(UIImage(named: "public_back_btn"))
  27. button.title("登录")
  28. button.mediumFont(17)
  29. button.textColor(QSLColor.Color_202020)
  30. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  31. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  32. return button
  33. }()
  34. lazy var logoImageView: UIImageView = {
  35. let imageView = UIImageView()
  36. imageView.image = UIImage(named: "mine_about_logo")
  37. return imageView
  38. }()
  39. lazy var phoneView: UIView = {
  40. let view = UIView()
  41. view.addRadius(radius: 6.rpx)
  42. view.backgroundColor = .hexStringColor(hexString: "#FAFAFA")
  43. return view
  44. }()
  45. lazy var phonePreLabel: UILabel = {
  46. let label = UILabel()
  47. label.text("+86")
  48. label.mediumFont(16)
  49. label.textColor = QSLColor.Color_202020
  50. return label
  51. }()
  52. lazy var phoneLineView: UIView = {
  53. let view = UIView()
  54. view.backgroundColor = .hexStringColor(hexString: "#E2E2E2")
  55. return view
  56. }()
  57. lazy var phoneTextField: UITextField = {
  58. let textField = UITextField()
  59. textField.maxTextNumber = 11
  60. textField.delegate = self
  61. textField.keyboardType = .numberPad
  62. textField.textColor = QSLColor.Color_202020
  63. textField.font = UIFont.textF(16)
  64. textField.placeholder = "请输入11位手机号码"
  65. textField.setPlaceholderAttribute(font: UIFont.textF(16), color: UIColor.hexStringColor(hexString: "#A7A7A7"))
  66. return textField
  67. }()
  68. lazy var codeView: UIView = {
  69. let view = UIView()
  70. view.addRadius(radius: 6.rpx)
  71. view.backgroundColor = .hexStringColor(hexString: "#FAFAFA")
  72. return view
  73. }()
  74. lazy var codeTextField: UITextField = {
  75. let textField = UITextField()
  76. textField.delegate = self
  77. textField.keyboardType = .numberPad
  78. textField.textColor = QSLColor.Color_202020
  79. textField.font = UIFont.textF(16)
  80. textField.placeholder = "请输入验证码"
  81. textField.setPlaceholderAttribute(font: UIFont.textF(16), color: UIColor.hexStringColor(hexString: "#A7A7A7"))
  82. return textField
  83. }()
  84. lazy var codeButton: UIButton = {
  85. let button = UIButton()
  86. button.addRadius(radius: 4.rpx)
  87. button.setBackgroundColor(.hexStringColor(hexString: "#15CBA1", alpha: 0.2), forState: .disabled)
  88. button.setBackgroundColor(.hexStringColor(hexString: "#15CBA1", alpha: 1), forState: .normal)
  89. button.title("发送验证码")
  90. button.textColor(.white)
  91. button.font(14)
  92. button.addTarget(self, action: #selector(codeButtonAction), for: .touchUpInside)
  93. return button
  94. }()
  95. lazy var selectBtn: UIButton = {
  96. let btn = UIButton()
  97. btn.image(UIImage(named: "public_select_btn_false"), .normal)
  98. btn.image(UIImage(named: "public_select_btn_true"), .selected)
  99. btn.addTarget(self, action: #selector(selectButtonAction), for: .touchUpInside)
  100. return btn
  101. }()
  102. lazy var serviceLabel: YYLabel = {
  103. let label = YYLabel()
  104. let attr = NSMutableAttributedString()
  105. let firstAttr = NSMutableAttributedString(string: "已阅读并同意")
  106. firstAttr.font(12)
  107. firstAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  108. attr.append(firstAttr)
  109. let blankAttr = NSMutableAttributedString(string: " ")
  110. blankAttr.font(12)
  111. attr.append(blankAttr)
  112. let privacyHL = YYTextHighlight()
  113. var privacyStr = "《隐私权政策》"
  114. let privacyText = NSMutableAttributedString(string: privacyStr)
  115. privacyText.font(12)
  116. privacyText.color(.hexStringColor(hexString: "#2F79FF"))
  117. privacyText.yy_setTextHighlight(privacyHL, range: NSRange(location: 0, length: privacyStr.count))
  118. privacyHL.tapAction = { [weak self] containerView, text, range, rect in
  119. self?.privacyAction()
  120. }
  121. attr.append(privacyText)
  122. attr.append(blankAttr)
  123. let andAttr = NSMutableAttributedString(string: "和")
  124. andAttr.font(12)
  125. andAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  126. attr.append(andAttr)
  127. attr.append(blankAttr)
  128. let serviceHL = YYTextHighlight()
  129. var serviceStr = "《用户协议》"
  130. let serviceText = NSMutableAttributedString(string: serviceStr)
  131. serviceText.font(12)
  132. serviceText.color(.hexStringColor(hexString: "#2F79FF"))
  133. serviceText.yy_setTextHighlight(serviceHL, range: NSRange(location: 0, length: serviceStr.count))
  134. serviceHL.tapAction = { [weak self] containerView, text, range, rect in
  135. self?.serviceAction()
  136. }
  137. attr.append(serviceText)
  138. label.attributedText = attr
  139. return label
  140. }()
  141. lazy var loginBtn: UIButton = {
  142. let btn = UIButton()
  143. btn.addRadius(radius: 22.rpx)
  144. 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) {
  145. btn.setBackgroundColor(UIColor(patternImage: image), forState: .disabled)
  146. }
  147. if let image = UIImage.gradient([.hexStringColor(hexString: "#15CBA1"), .hexStringColor(hexString: "#1FE0BA")], size: CGSize(width: 280.rpx, height: 44.rpx), locations: [0, 1], direction: .horizontal) {
  148. btn.setBackgroundColor(UIColor(patternImage: image), forState: .normal)
  149. }
  150. btn.title("登录")
  151. btn.textColor(.white)
  152. btn.mediumFont(16)
  153. btn.addTarget(self, action: #selector(loginButtonAction), for: .touchUpInside)
  154. return btn
  155. }()
  156. override func viewDidLoad() {
  157. super.viewDidLoad()
  158. initializeView()
  159. if let type = self.type {
  160. switch type {
  161. case .mine:
  162. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1001])
  163. case .add:
  164. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1002])
  165. case .road:
  166. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1003])
  167. case .contact:
  168. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1004])
  169. case .onQucikLogin:
  170. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1005])
  171. case .member:
  172. gravityInstance?.track(QSLGravityConst.login_show, properties: ["id": 1006])
  173. }
  174. }
  175. }
  176. }
  177. extension QSLLoginViewController {
  178. @objc func privacyAction() {
  179. let vc = QSLWebViewController()
  180. vc.webUrl = QSLConfig.AppPrivacyAgreementLink
  181. vc.title = "隐私政策"
  182. self.navigationController?.pushViewController(vc, animated: true)
  183. }
  184. @objc func serviceAction() {
  185. let vc = QSLWebViewController()
  186. vc.webUrl = QSLConfig.AppServiceAgreementLink
  187. vc.title = "服务协议"
  188. self.navigationController?.pushViewController(vc, animated: true)
  189. }
  190. @objc func selectButtonAction() {
  191. gravityInstance?.track(QSLGravityConst.login_agree)
  192. self.selectBtn.isSelected = !self.selectBtn.isSelected
  193. }
  194. // 验证码
  195. @objc func codeButtonAction() {
  196. gravityInstance?.track(QSLGravityConst.login_code)
  197. if let phone = self.phoneTextField.text, phone.count == 11 {
  198. codeButton.countDown(60)
  199. QSLNetwork().request(.userCode(dict: ["phone": phone]), success: { response in
  200. }, fail: { code, error in
  201. gravityInstance?.track(QSLGravityConst.login_code_fail, properties: ["id": 1001])
  202. self.view.toast(text: "发送失败")
  203. })
  204. } else {
  205. gravityInstance?.track(QSLGravityConst.login_code_fail, properties: ["id": 1002])
  206. self.view.toast(text: "请输入正确的手机号码")
  207. }
  208. }
  209. // 登录按钮
  210. @objc func loginButtonAction() {
  211. gravityInstance?.track(QSLGravityConst.login_click)
  212. guard let phone = self.phoneTextField.text, phone.count == 11 else {
  213. self.view.toast(text: "请输入正确的手机号码")
  214. return
  215. }
  216. guard let code = self.codeTextField.text else {
  217. self.view.toast(text: "请输入验证码")
  218. return
  219. }
  220. if !self.selectBtn.isSelected {
  221. gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1001])
  222. self.view.toast(text: "请先阅读并同意《隐私权政策》和《用户协议》")
  223. return
  224. }
  225. QSLLoading.show()
  226. QSLNetwork().request(.userLogin(dict: ["phone": phone, "code": code]), success: { response in
  227. QSLLoading.hide()
  228. let authToken = response.toJSON(modelKey: "data>authToken").stringValue
  229. QSLBaseManager.shared.loginUpdateUser(authToken: authToken, phone: phone)
  230. UIApplication.keyWindow?.toast(text: "登录成功")
  231. gravityInstance?.track(QSLGravityConst.login_success)
  232. // 发送通知
  233. NotificationCenter.default.post(name: QSLNotification.QSLLogin, object: nil)
  234. // 发送通知
  235. NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  236. // 通知快捷登录
  237. if self.type == .onQucikLogin {
  238. self.navigationController?.popToRootViewController(animated: true)
  239. } else {
  240. // 返回
  241. self.backBtnAction()
  242. }
  243. }, fail: { code, error in
  244. if code == 1005 {
  245. gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1002])
  246. } else {
  247. gravityInstance?.track(QSLGravityConst.login_fail, properties: ["id": 1003])
  248. }
  249. QSLLoading.hide()
  250. self.view.toast(text: error)
  251. })
  252. }
  253. }
  254. extension QSLLoginViewController: UITextFieldDelegate {
  255. }
  256. extension QSLLoginViewController {
  257. func initializeView() {
  258. self.view.backgroundColor = .white
  259. self.view.addSubview(loginBg)
  260. loginBg.snp.makeConstraints { make in
  261. make.left.top.right.equalToSuperview()
  262. }
  263. self.view.addSubview(backButton)
  264. backButton.snp.makeConstraints { make in
  265. make.size.equalTo(CGSize(width: 65.rpx, height: 25.rpx))
  266. make.left.equalTo(12.rpx)
  267. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  268. }
  269. self.view.addSubview(logoImageView)
  270. logoImageView.snp.makeConstraints { make in
  271. make.size.equalTo(CGSize(width: 70.rpx, height: 70.rpx))
  272. make.centerX.equalToSuperview()
  273. make.top.equalTo(backButton.snp.bottom).offset(30.rpx)
  274. }
  275. self.view.addSubview(phoneView)
  276. phoneView.addSubview(phonePreLabel)
  277. phoneView.addSubview(phoneLineView)
  278. phoneView.addSubview(phoneTextField)
  279. phoneView.snp.makeConstraints { make in
  280. make.left.equalTo(24.rpx)
  281. make.right.equalTo(-24.rpx)
  282. make.height.equalTo(50.rpx)
  283. make.top.equalTo(logoImageView.snp.bottom).offset(40.rpx)
  284. }
  285. phonePreLabel.snp.makeConstraints { make in
  286. make.left.equalTo(12.rpx)
  287. make.centerY.equalToSuperview()
  288. }
  289. phoneLineView.snp.makeConstraints { make in
  290. make.top.equalTo(15.rpx)
  291. make.bottom.equalTo(-15.rpx)
  292. make.left.equalTo(49.rpx)
  293. make.width.equalTo(1.rpx)
  294. }
  295. phoneTextField.snp.makeConstraints { make in
  296. make.left.equalTo(phoneLineView.snp.right).offset(25.rpx)
  297. make.right.equalTo(-12.rpx)
  298. make.top.bottom.equalTo(0)
  299. }
  300. self.view.addSubview(codeView)
  301. codeView.addSubview(codeTextField)
  302. codeView.addSubview(codeButton)
  303. codeView.snp.makeConstraints { make in
  304. make.left.equalTo(24.rpx)
  305. make.right.equalTo(-24.rpx)
  306. make.height.equalTo(50.rpx)
  307. make.top.equalTo(phoneView.snp.bottom).offset(12.rpx)
  308. }
  309. codeButton.snp.makeConstraints { make in
  310. make.size.equalTo(CGSize(width: 90.rpx, height: 32.rpx))
  311. make.right.equalTo(-12.rpx)
  312. make.centerY.equalToSuperview()
  313. }
  314. codeTextField.snp.makeConstraints { make in
  315. make.left.equalTo(12.rpx)
  316. make.top.bottom.equalTo(0)
  317. make.right.equalTo(codeButton.snp.left).offset(-12.rpx)
  318. }
  319. self.view.addSubview(selectBtn)
  320. self.view.addSubview(serviceLabel)
  321. selectBtn.snp.makeConstraints { make in
  322. make.size.equalTo(CGSize(width: 12.rpx, height: 12.rpx))
  323. make.left.equalTo(25.rpx)
  324. make.top.equalTo(codeView.snp.bottom).offset(14.rpx)
  325. }
  326. serviceLabel.snp.makeConstraints { make in
  327. make.centerY.equalTo(selectBtn.snp.centerY)
  328. make.left.equalTo(selectBtn.snp.right).offset(4.rpx)
  329. }
  330. self.view.addSubview(loginBtn)
  331. loginBtn.snp.makeConstraints { make in
  332. make.size.equalTo(CGSize(width: 280.rpx, height: 44.rpx))
  333. make.centerX.equalToSuperview()
  334. make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom - 95.rpx)
  335. }
  336. }
  337. }