LoginViewController.swift 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. //
  2. // LoginViewController.swift
  3. // MTP2_iOS
  4. //
  5. // Created by zhongyuan on 2018/5/10.
  6. // Copyright © 2018年 zhongyuan.All rights reserved.
  7. //
  8. import UIKit
  9. import NVActivityIndicatorView
  10. import WHToast
  11. import SwiftyAttributes
  12. import SafariServices
  13. import SwiftDate
  14. /// 登录视图容器管理类
  15. class LoginViewController: BaseTableViewController<LsLoginUserModel>, UITextFieldDelegate {
  16. // MARK: - 生命周期
  17. private static let TAG_LOGIN = 100
  18. private static let TAG_REGIEST = 101
  19. private static let TAG_PULL = 102
  20. private static let TAG_WACHAT = 103
  21. private static let TAG_ALIPAY = 104
  22. private static let TAG_PHONE_LOGIN = 105
  23. private static let TAG_FORGETPWD = 106
  24. /// 账户名称
  25. @IBOutlet weak var usernameTextField: UITextField!
  26. /// 账户密码
  27. @IBOutlet weak var passwordTextField: UITextField!
  28. /// 登录按钮
  29. @IBOutlet weak var loginButton: UIButton!
  30. /// 手机号码登录
  31. @IBOutlet weak var phoneLoginButton: UIButton! {
  32. didSet {
  33. phoneLoginButton.isHidden = !((ConfigUtils.getValue(key: .SupportMobileLogin) as? Bool) ?? true)
  34. }
  35. }
  36. /// 是否记住密码
  37. @IBOutlet weak var savePwd: UISwitch!
  38. /// 账户信息下拉按钮
  39. @IBOutlet weak var userPull: UIButton!
  40. /// 用户信息
  41. @IBOutlet weak var userTableView: UITableView! {
  42. didSet {
  43. userTableView.layer.cornerRadius = 5.0
  44. userTableView.layer.borderWidth = 0.5
  45. userTableView.layer.borderColor = UIColorFromHex(rgbValue: 0xe0e0e0).cgColor
  46. userTableView.layer.masksToBounds = true
  47. }
  48. }
  49. /// cell的高度约束
  50. @IBOutlet weak var cellConstraints: NSLayoutConstraint!
  51. /// 微信
  52. @IBOutlet weak var weixinButton: UIButton!
  53. /// 支付宝
  54. @IBOutlet weak var alipayButton: UIButton!
  55. /// 忘记密码
  56. @IBOutlet weak var forgetPwdButton: UIButton! {
  57. didSet {
  58. forgetPwdButton.isHidden = !((ConfigUtils.getValue(key: .SupportResetPwd) as? Bool) ?? true)
  59. }
  60. }
  61. /// 版本号
  62. @IBOutlet weak var versionLabel: UILabel! {
  63. didSet {
  64. versionLabel.text = "版本号:V" + app_Version
  65. }
  66. }
  67. /// 是否张开状态
  68. private var isExpand = false
  69. // MARK: - 生命周期相关
  70. override func viewDidLoad() {
  71. super.viewDidLoad()
  72. /// 隐藏导航栏
  73. self.navigationController?.setNavigationBarHidden(true, animated: true)
  74. /// Loading
  75. addLoadingView()
  76. /// 界面内容初始化
  77. buildView()
  78. /// 数据初始化
  79. initData()
  80. /// 初始化用户信息
  81. initUser()
  82. }
  83. override func viewDidAppear(_ animated: Bool) {
  84. super.viewDidAppear(animated)
  85. /// stopAnimating
  86. if let isAnimating = self._anim?.isAnimating,
  87. isAnimating { self._anim?.stopAnimating() }
  88. }
  89. // MARK: - 初始化相关
  90. /// 数据初始化
  91. func initData() {
  92. /// 请求app版本更新
  93. self.requestAppVersionUpdate()
  94. }
  95. /// 界面内容初始化
  96. func buildView() {
  97. /// 设置attributedPlaceholder
  98. usernameTextField.attributedPlaceholder = "用户名/账号/手机号".withTextColor(Color_placeholder_text)
  99. passwordTextField.attributedPlaceholder = "请输入您的密码".withTextColor(Color_placeholder_text)
  100. /// 获取是否记录密码
  101. self.savePwd.isOn = UserDefaultsUtils.isSavePwd()
  102. /// 记住了密码 并且密码不为空 并且6小时有效
  103. if self.savePwd.isOn,
  104. let pwd = UserDefaultsUtils.savePwd(),
  105. let date = UserDefaultsUtils.savePwdTime(),
  106. ((Date()-date).hour ?? 0)<=6 {
  107. /// 填入密码
  108. passwordTextField.text = pwd
  109. }
  110. /// 设置cell标识
  111. cellReuseIdentifier = "LoginUserCellID"
  112. /// tableView 设置
  113. userTableView.rowHeight = 44.0
  114. }
  115. // MARK: - 用户交互相关
  116. @IBAction func viewPassed(_ sender: UIButton) {
  117. if self.usernameTextField.isFirstResponder {
  118. self.usernameTextField.resignFirstResponder()
  119. }
  120. if self.passwordTextField.isFirstResponder {
  121. self.passwordTextField.resignFirstResponder()
  122. }
  123. switch sender.tag {
  124. case LoginViewController.TAG_LOGIN:
  125. if let _ = MTP2BusinessCore.shared.address {
  126. startLogin()
  127. } else {
  128. /// startAnimating
  129. self._anim?.startAnimating()
  130. /// requestAppAdress
  131. MTP2BusinessCore.shared.requestAppAdress { (isComplete, error) in
  132. DispatchQueue.main.async {
  133. /// stopAnimating
  134. self._anim?.stopAnimating()
  135. if !isComplete {
  136. WHToast.showError(withMessage: "登录失败,获取链路失败!", duration: 2.0, finishHandler: {})
  137. return
  138. }
  139. /// 开始登录
  140. self.startLogin()
  141. }
  142. }
  143. }
  144. case LoginViewController.TAG_PULL: /// 帐户列表
  145. getAllUser()
  146. case LoginViewController.TAG_FORGETPWD: /// 忘记密码
  147. /// 进入到重置密码
  148. self.present(storyboardName: "ResetPwd", storyboardId: "ResetPwdFirstStepID")
  149. case LoginViewController.TAG_PHONE_LOGIN: /// 帐户注册
  150. guard let url = URL(string: MTP2BusinessCore.shared.address?.mobileOpenUrl ?? "") else { return }
  151. let safriViewController = SFSafariViewController(url: url)
  152. safriViewController.delegate = self
  153. self.present(safriViewController, animated: true, completion: {})
  154. default:
  155. if (self.navigationController?.viewControllers.count ?? 0) > 1 {
  156. self.navigationController?.popViewController(animated: true)
  157. } else {
  158. self.dismiss(animated: true, completion: {})
  159. }
  160. }
  161. }
  162. @IBAction func onValueChanged(_ sender: UISwitch) {
  163. /// 记录是否记住密码
  164. UserDefaultsUtils.setIsSavePwd(sender.isOn)
  165. }
  166. /// 获取保存的用户账号
  167. func initUser() {
  168. if let userInfo = try? DatabaseHelper.getUsers(type: Int16(0)) {
  169. tableCellModels = userInfo.compactMap({ LsLoginUserModel(source: $0) }).sorted(by: { (obj1, obj2) -> Bool in
  170. return obj1.loginDate>obj2.loginDate
  171. })
  172. usernameTextField.text = tableCellModels[0].loginID
  173. userPull.isHidden = userInfo.count > 0 ? false : true
  174. } else {
  175. usernameTextField.text = ""
  176. tableCellModels.removeAll()
  177. userPull.isHidden = true
  178. }
  179. }
  180. /// 显示所有的账户信息
  181. func getAllUser() {
  182. /// 是否展开
  183. isExpand = !isExpand
  184. /// 是否隐藏
  185. self.userTableView.isHidden = !self.isExpand
  186. /// 约束
  187. self.cellConstraints.constant = 0.0
  188. /// 动画
  189. UIView.animate(withDuration: 0.3) {
  190. self.cellConstraints.constant = self.isExpand ? CGFloat(self.tableCellModels.count > 5 ? 5 : self.tableCellModels.count) * 44 : 0
  191. self.view.layoutIfNeeded()
  192. }
  193. userTableView.reloadData()
  194. }
  195. // MARK: - 登录相关
  196. /// 用户登录校验
  197. ///
  198. /// - Returns: 是否成功
  199. private func checkValue() -> Bool {
  200. if let account = self.usernameTextField.text {
  201. if account.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty {
  202. WHToast.showError(withMessage: "请输入登录账户", duration: 1.0) {
  203. self.usernameTextField.becomeFirstResponder()
  204. }
  205. return false
  206. }
  207. }
  208. if let password = self.passwordTextField.text {
  209. if password.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty {
  210. WHToast.showError(withMessage: "请输入账户密码", duration: 1.0) {
  211. self.passwordTextField.becomeFirstResponder()
  212. }
  213. return false
  214. }
  215. }
  216. return true
  217. }
  218. /// 登录方法
  219. func startLogin() {
  220. /// 异常
  221. guard checkValue(),
  222. let accountManager = MTP2BusinessCore.shared.accountManager,
  223. let account = self.usernameTextField.text,
  224. let password = self.passwordTextField.text else { return }
  225. /// startAnimating
  226. self._anim?.startAnimating()
  227. /// isUserInteractionEnabled
  228. self.view.isUserInteractionEnabled = false
  229. /// isEnabled
  230. self.loginButton.isEnabled = false
  231. let faidBlock = { (error: ErrorInfo?) in
  232. DispatchQueue.main.async {
  233. self._anim?.stopAnimating()
  234. self.view.isUserInteractionEnabled = true
  235. self.loginButton.isEnabled = true
  236. if let error = error,
  237. error.retCode == 1003,
  238. let loginrsp = accountManager.loginRsp {
  239. let message = "还剩\(loginrsp.pwdWrongLockCnt - loginrsp.pwdWrongCnt)次错误机会,账号或密码不匹配达到\(loginrsp.pwdWrongLockCnt)次,登录账号将锁定\(loginrsp.loginLockHourNum)小时。请联系管理员966000处理。" + "您也可通过手机验证码登录!"
  240. self.showHintController(title: "提示", message: message)
  241. } else {
  242. self.showErrorMessgae(error: error)
  243. }
  244. }
  245. }
  246. guard let trade_address = MTP2BusinessCore.shared.address?.tradeHost,
  247. let trade_port = MTP2BusinessCore.shared.address?.tradePort,
  248. let intPort = UInt16(trade_port) else { return }
  249. /// 每次登录前重新请求地址信息
  250. MTP2BusinessCore.shared.requestAppAdress(true) { (isAddress, er) in
  251. if !isAddress {
  252. faidBlock(er)
  253. return
  254. }
  255. /// 获取登录ID
  256. accountManager.getUserLoginID(account) { (isSuccess, err, loginId) in
  257. if !isSuccess {
  258. faidBlock(err)
  259. return
  260. }
  261. DispatchQueue.main.async {
  262. accountManager.login(address: trade_address, port: intPort, userName: loginId!, password: password, deviceID: NSUUID().uuidString, version: app_Version) { isCompleted, error in
  263. if isCompleted {
  264. /// 用户与商品信息统一查询
  265. accountManager.queryAccountAndGoods(callback: { (isCompleted, error) in
  266. if isCompleted {
  267. DispatchQueue.main.async {
  268. /// 如果有 先删除
  269. if let _ = try? DatabaseHelper.getUser(userID: MTP2BusinessCore.shared.getUserID(), type: Int16(0)) {
  270. try? DatabaseHelper.deleteUser(userID: MTP2BusinessCore.shared.getUserID())
  271. }
  272. DispatchQueue.global().asyncAfter(deadline: DispatchTime.now()+0.5, execute: {
  273. /// 记录本地用户信息
  274. try? DatabaseHelper.addUser(userID: MTP2BusinessCore.shared.getUserID(), loginID: account, loginDate: Date(), type: Int16(0))
  275. })
  276. if self.savePwd.isOn {
  277. /// 记住密码和时间
  278. UserDefaultsUtils.setSavePwd(password)
  279. UserDefaultsUtils.setSavePwdTime(Date())
  280. }
  281. self._anim?.stopAnimating()
  282. self.view.isUserInteractionEnabled = true
  283. self.loginButton.isEnabled = true
  284. /// 进入主界面
  285. if let mainTabBarController: UITabBarController = self.storyboard?.instantiateViewController(withIdentifier: "MainTabBarController") as? UITabBarController {
  286. /// 设置根视图
  287. (UIApplication.shared.delegate as? AppDelegate)?.window?.rootViewController = mainTabBarController
  288. }
  289. }
  290. } else {
  291. faidBlock(error)
  292. }
  293. })
  294. } else {
  295. faidBlock(error)
  296. }
  297. }
  298. }
  299. }
  300. }
  301. }
  302. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  303. super.touchesBegan(touches, with: event)
  304. /// 关闭
  305. if !userTableView.isHidden {
  306. isExpand = false
  307. userTableView.isHidden = true
  308. }
  309. }
  310. // MARK: - 版本更新相关
  311. /// app检测版本更新
  312. fileprivate func requestAppVersionUpdate() {
  313. /// 地址信息为空
  314. guard let updateUrl = ConfigUtils.getServiceUrl(resourceType: .UpdateUrl),
  315. updateUrl != "" else { return }
  316. /// 请求更新
  317. HttpUtils.callInterface(url: updateUrl, type: .GET, params: nil) { (isComplete, response) in
  318. if isComplete == true,
  319. let dic = response as? NSDictionary, let arrays = (dic["results"] as? [NSDictionary]), arrays.count != 0 {
  320. DispatchQueue.main.async {
  321. guard let appStoreVersion = (arrays[0])["version"] as? String else {return}
  322. guard let releaseNotes = (arrays[0])["releaseNotes"] as? String else {return}
  323. guard let trackViewUrl = (arrays[0])["trackViewUrl"] as? String else {return}
  324. let storeStr = NSString(string: appStoreVersion).replacingOccurrences(of: ".", with: "")
  325. let appStr = NSString(string: app_Version).replacingOccurrences(of: ".", with: "")
  326. if storeStr > appStr {
  327. /// 提示更新
  328. AppUpdateAlert.showUpdateAlert(version: appStoreVersion, description: releaseNotes, trackViewUrl)
  329. }
  330. }
  331. }
  332. }
  333. }
  334. // MARK: - UITextFieldDelegate
  335. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  336. /// 失去焦点
  337. self.view.endEditing(true)
  338. /// 开始登录
  339. if textField == passwordTextField {
  340. if let _ = MTP2BusinessCore.shared.address {
  341. startLogin()
  342. } else {
  343. /// startAnimating
  344. self._anim?.startAnimating()
  345. /// requestAppAdress
  346. MTP2BusinessCore.shared.requestAppAdress { (isComplete, error) in
  347. DispatchQueue.main.async {
  348. /// stopAnimating
  349. self._anim?.stopAnimating()
  350. if !isComplete {
  351. WHToast.showError(withMessage: "登录失败,获取链路失败!", duration: 2.0, finishHandler: {})
  352. return
  353. }
  354. /// 开始登录
  355. self.startLogin()
  356. }
  357. }
  358. }
  359. }
  360. return true
  361. }
  362. func textFieldDidBeginEditing(_ textField: UITextField) {
  363. if Is_Iphone_678 {
  364. if textField == usernameTextField {
  365. UIView.animate(withDuration: 0.3) { self.view.top = -100.0 }
  366. }
  367. if textField == passwordTextField {
  368. UIView.animate(withDuration: 0.3) { self.view.top = -140.0 }
  369. }
  370. }
  371. if !userTableView.isHidden {
  372. isExpand = false
  373. userTableView.isHidden = true
  374. }
  375. }
  376. func textFieldDidEndEditing(_ textField: UITextField) {
  377. UIView.animate(withDuration: 0.3) { self.view.top = 0.0 }
  378. }
  379. // MARK: - UITableViewDelegate
  380. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  381. super.tableView(tableView, didSelectRowAt: indexPath)
  382. /// 显示选中的账户信息
  383. usernameTextField.text = tableCellModels[indexPath.row].loginID
  384. userTableView.isHidden = true
  385. /// 清空密码输入框
  386. passwordTextField.text = ""
  387. }
  388. }
  389. // MARK: - LoginUserCellDelegate
  390. extension LoginViewController: LoginUserCellDelegate {
  391. func delete(rowNum: Int) {
  392. do {
  393. try DatabaseHelper.deleteUser(userID: UInt32(tableCellModels[rowNum].userID))
  394. } catch {
  395. WHToast.showError(withMessage: error.localizedDescription, duration: 1.5, finishHandler: {})
  396. }
  397. tableCellModels.remove(at: rowNum)
  398. userTableView.deleteRows(at:[IndexPath(row: rowNum, section: 0)], with: .right)
  399. if tableCellModels.count == 0 { userPull.isHidden = true }
  400. UIView.animate(withDuration: 0.3) {
  401. self.cellConstraints.constant = CGFloat(self.tableCellModels.count > 5 ? 5 : self.tableCellModels.count) * 44
  402. self.view.layoutIfNeeded()
  403. }
  404. }
  405. }
  406. extension LoginViewController: UIPopoverPresentationControllerDelegate {
  407. func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
  408. return .none
  409. }
  410. }
  411. extension LoginViewController: SFSafariViewControllerDelegate {
  412. func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
  413. controller.dismiss(animated: true, completion: {})
  414. }
  415. }