LoginViewController.swift 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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. /// 获取登录ID
  250. accountManager.getUserLoginID(account) { (isSuccess, err, loginId) in
  251. if !isSuccess {
  252. faidBlock(err)
  253. return
  254. }
  255. DispatchQueue.main.async {
  256. accountManager.login(address: trade_address, port: intPort, userName: loginId!, password: password, deviceID: NSUUID().uuidString, version: app_Version) { isCompleted, error in
  257. if isCompleted {
  258. /// 用户与商品信息统一查询
  259. accountManager.queryAccountAndGoods(callback: { (isCompleted, error) in
  260. if isCompleted {
  261. DispatchQueue.main.async {
  262. /// 如果有 先删除
  263. if let _ = try? DatabaseHelper.getUser(userID: MTP2BusinessCore.shared.getUserID(), type: Int16(0)) {
  264. try? DatabaseHelper.deleteUser(userID: MTP2BusinessCore.shared.getUserID())
  265. }
  266. DispatchQueue.global().asyncAfter(deadline: DispatchTime.now()+0.5, execute: {
  267. /// 记录本地用户信息
  268. try? DatabaseHelper.addUser(userID: MTP2BusinessCore.shared.getUserID(), loginID: account, loginDate: Date(), type: Int16(0))
  269. })
  270. if self.savePwd.isOn {
  271. /// 记住密码和时间
  272. UserDefaultsUtils.setSavePwd(password)
  273. UserDefaultsUtils.setSavePwdTime(Date())
  274. }
  275. self._anim?.stopAnimating()
  276. self.view.isUserInteractionEnabled = true
  277. self.loginButton.isEnabled = true
  278. /// 进入主界面
  279. if let mainTabBarController: UITabBarController = self.storyboard?.instantiateViewController(withIdentifier: "MainTabBarController") as? UITabBarController {
  280. /// 设置根视图
  281. (UIApplication.shared.delegate as? AppDelegate)?.window?.rootViewController = mainTabBarController
  282. }
  283. }
  284. } else {
  285. faidBlock(error)
  286. }
  287. })
  288. } else {
  289. faidBlock(error)
  290. }
  291. }
  292. }
  293. }
  294. }
  295. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  296. super.touchesBegan(touches, with: event)
  297. /// 关闭
  298. if !userTableView.isHidden {
  299. isExpand = false
  300. userTableView.isHidden = true
  301. }
  302. }
  303. // MARK: - 版本更新相关
  304. /// app检测版本更新
  305. fileprivate func requestAppVersionUpdate() {
  306. /// 地址信息为空
  307. guard let updateUrl = ConfigUtils.getServiceUrl(resourceType: .UpdateUrl),
  308. updateUrl != "" else { return }
  309. /// 请求更新
  310. HttpUtils.callInterface(url: updateUrl, type: .GET, params: nil) { (isComplete, response) in
  311. if isComplete == true,
  312. let dic = response as? NSDictionary, let arrays = (dic["results"] as? [NSDictionary]), arrays.count != 0 {
  313. DispatchQueue.main.async {
  314. guard let appStoreVersion = (arrays[0])["version"] as? String else {return}
  315. guard let releaseNotes = (arrays[0])["releaseNotes"] as? String else {return}
  316. guard let trackViewUrl = (arrays[0])["trackViewUrl"] as? String else {return}
  317. let storeStr = NSString(string: appStoreVersion).replacingOccurrences(of: ".", with: "")
  318. let appStr = NSString(string: app_Version).replacingOccurrences(of: ".", with: "")
  319. if storeStr > appStr {
  320. /// 提示更新
  321. AppUpdateAlert.showUpdateAlert(version: appStoreVersion, description: releaseNotes, trackViewUrl)
  322. }
  323. }
  324. }
  325. }
  326. }
  327. // MARK: - UITextFieldDelegate
  328. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  329. /// 失去焦点
  330. self.view.endEditing(true)
  331. /// 开始登录
  332. if textField == passwordTextField {
  333. if let _ = MTP2BusinessCore.shared.address {
  334. startLogin()
  335. } else {
  336. /// startAnimating
  337. self._anim?.startAnimating()
  338. /// requestAppAdress
  339. MTP2BusinessCore.shared.requestAppAdress { (isComplete, error) in
  340. DispatchQueue.main.async {
  341. /// stopAnimating
  342. self._anim?.stopAnimating()
  343. if !isComplete {
  344. WHToast.showError(withMessage: "登录失败,获取链路失败!", duration: 2.0, finishHandler: {})
  345. return
  346. }
  347. /// 开始登录
  348. self.startLogin()
  349. }
  350. }
  351. }
  352. }
  353. return true
  354. }
  355. func textFieldDidBeginEditing(_ textField: UITextField) {
  356. if Is_Iphone_678 {
  357. if textField == usernameTextField {
  358. UIView.animate(withDuration: 0.3) { self.view.top = -100.0 }
  359. }
  360. if textField == passwordTextField {
  361. UIView.animate(withDuration: 0.3) { self.view.top = -140.0 }
  362. }
  363. }
  364. if !userTableView.isHidden {
  365. isExpand = false
  366. userTableView.isHidden = true
  367. }
  368. }
  369. func textFieldDidEndEditing(_ textField: UITextField) {
  370. UIView.animate(withDuration: 0.3) { self.view.top = 0.0 }
  371. }
  372. // MARK: - UITableViewDelegate
  373. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  374. super.tableView(tableView, didSelectRowAt: indexPath)
  375. usernameTextField.text = tableCellModels[indexPath.row].loginID
  376. userTableView.isHidden = true
  377. }
  378. }
  379. // MARK: - LoginUserCellDelegate
  380. extension LoginViewController: LoginUserCellDelegate {
  381. func delete(rowNum: Int) {
  382. do {
  383. try DatabaseHelper.deleteUser(userID: UInt32(tableCellModels[rowNum].userID))
  384. } catch {
  385. WHToast.showError(withMessage: error.localizedDescription, duration: 1.5, finishHandler: {})
  386. }
  387. tableCellModels.remove(at: rowNum)
  388. userTableView.deleteRows(at:[IndexPath(row: rowNum, section: 0)], with: .right)
  389. if tableCellModels.count == 0 { userPull.isHidden = true }
  390. UIView.animate(withDuration: 0.3) {
  391. self.cellConstraints.constant = CGFloat(self.tableCellModels.count > 5 ? 5 : self.tableCellModels.count) * 44
  392. self.view.layoutIfNeeded()
  393. }
  394. }
  395. }
  396. extension LoginViewController: UIPopoverPresentationControllerDelegate {
  397. func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
  398. return .none
  399. }
  400. }
  401. extension LoginViewController: SFSafariViewControllerDelegate {
  402. func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
  403. controller.dismiss(animated: true, completion: {})
  404. }
  405. }