QSLContactController.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. //
  2. // QSLContactController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2024/12/11.
  6. //
  7. import UIKit
  8. import YYText
  9. enum QSLContactJumpPage: Int {
  10. case shortcut = 1 // 快捷键
  11. case mine = 2 // 我的页面
  12. }
  13. class QSLContactController: QSLBaseController {
  14. var type: QSLContactJumpPage?
  15. var contactList: [QSLContactModel]?
  16. lazy var bgImageView: UIImageView = {
  17. let imageView = UIImageView()
  18. imageView.image = UIImage(named: "mine_bg")
  19. return imageView
  20. }()
  21. lazy var backButton: UIButton = {
  22. let button = UIButton()
  23. button.image(UIImage(named: "public_back_btn"))
  24. button.title("添加紧急联系人")
  25. button.mediumFont(17)
  26. button.textColor(QSLColor.Color_202020)
  27. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  28. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  29. return button
  30. }()
  31. lazy var contactIcon: UIImageView = {
  32. let imageView = UIImageView()
  33. imageView.image = UIImage(named: "contact_icon")
  34. return imageView
  35. }()
  36. lazy var contactLabel: UILabel = {
  37. let label = UILabel()
  38. label.textAlignment = .center
  39. label.numberOfLines = 0
  40. label.text("使用一键求助,需要添加正确的紧急联系人手机号码,您的联系人将会收到短信以及APP消息通知。")
  41. label.font(13)
  42. label.textColor = .hexStringColor(hexString: "#404040")
  43. label.changeLineSpace(space: 5)
  44. return label
  45. }()
  46. lazy var titleIcon: UIImageView = {
  47. let imageView = UIImageView()
  48. imageView.image = UIImage(named: "contact_title_icon")
  49. return imageView
  50. }()
  51. lazy var addBtn: UIButton = {
  52. let btn = UIButton()
  53. btn.title("添加联系人")
  54. btn.textColor(.hexStringColor(hexString: "#15CBA1"))
  55. btn.mediumFont(14)
  56. btn.image(UIImage(named: "contact_add_icon"))
  57. btn.addTarget(self, action: #selector(addBtnAction), for: .touchUpInside)
  58. return btn
  59. }()
  60. lazy var emptyAddLabel: YYLabel = {
  61. let label = YYLabel()
  62. let attr = NSMutableAttributedString()
  63. let firstAttr = NSMutableAttributedString(string: "未添加联系人,")
  64. firstAttr.font(14)
  65. firstAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  66. attr.append(firstAttr)
  67. let addHL = YYTextHighlight()
  68. var addStr = "点我添加"
  69. let addText = NSMutableAttributedString(string: addStr)
  70. addText.font(14)
  71. addText.color(.hexStringColor(hexString: "#15CBA1"))
  72. addText.yy_setTextHighlight(addHL, range: NSRange(location: 0, length: addStr.count))
  73. addHL.tapAction = { [weak self] containerView, text, range, rect in
  74. self?.addBtnAction()
  75. }
  76. attr.append(addText)
  77. label.attributedText = attr
  78. return label
  79. }()
  80. lazy var contactTableView: UITableView = {
  81. let tableView = UITableView(frame: .zero, style: .grouped)
  82. tableView.backgroundColor = QSLColor.backGroundColor
  83. tableView.separatorStyle = .none
  84. tableView.showsVerticalScrollIndicator = false
  85. tableView.delegate = self
  86. tableView.dataSource = self
  87. tableView.tableViewNeverAdjustContentInset()
  88. tableView.bounces = true
  89. tableView.isUserInteractionEnabled = true
  90. tableView.isScrollEnabled = true
  91. tableView.contentInsetAdjustmentBehavior = .never
  92. tableView.register(cellClass: QSLContactCell.self)
  93. return tableView
  94. }()
  95. lazy var bottomView: UIView = {
  96. let view = UIView(frame: CGRect(x: 0, y: 0, width: QSLConst.qsl_kScreenW, height: 76.rpx))
  97. view.backgroundColor = .white
  98. view.addFourCorner(topLeft: 12.rpx, topRight: 12.rpx, bottomLeft: 0, bottomRight: 0)
  99. view.layer.shadowOffset = CGSize(width: 0, height: -1)
  100. view.layer.shadowColor = UIColor.hexStringColor(hexString: "#A7A7A7", alpha: 0.1).cgColor
  101. view.layer.shadowOpacity = 5
  102. view.layer.shadowRadius = 0
  103. return view
  104. }()
  105. lazy var sendBtn: UIButton = {
  106. let btn = UIButton()
  107. btn.addRadius(radius: 22.rpx)
  108. btn.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FF5146"), color2: .hexStringColor(hexString: "#FF766D"), width: QSLConst.qsl_kScreenW - 32.rpx, height: 44.rpx, direction: .horizontal)
  109. btn.title("一键发送求助")
  110. btn.mediumFont(16)
  111. btn.textColor(.white)
  112. btn.addTarget(self, action: #selector(sendAllBtnAction), for: .touchUpInside)
  113. return btn
  114. }()
  115. override func viewDidLoad() {
  116. super.viewDidLoad()
  117. self.initView()
  118. self.requestContactList()
  119. NotificationCenter.default.addObserver(self, selector: #selector(requestContactList), name: QSLNotification.QSLRefreshContact, object: nil)
  120. if let type = self.type {
  121. if type == .mine {
  122. gravityInstance?.track(QSLGravityConst.contact_show, properties: ["id": 1002])
  123. } else {
  124. gravityInstance?.track(QSLGravityConst.contact_show, properties: ["id": 1001])
  125. }
  126. }
  127. }
  128. }
  129. extension QSLContactController {
  130. @objc func addBtnAction() {
  131. if !QSLBaseManager.shared.isLogin() {
  132. if let view = self.tabBarController?.view {
  133. QSLAlertView.alert(view: view, title: "温馨提示", content: "登录即可体验查看轨迹记录", secondBtnClosure: {
  134. QSLJumpManager.shared.pushToLogin(type: .contact)
  135. })
  136. }
  137. return
  138. }
  139. if !QSLBaseManager.shared.isVip() {
  140. QSLJumpManager.shared.pushToVip(type: .contact)
  141. return
  142. }
  143. QSLContactAddAlertView.alert(vc: self) { phone in
  144. self.requestAddContact(phone: phone)
  145. }
  146. }
  147. @objc func sendAllBtnAction() {
  148. gravityInstance?.track(QSLGravityConst.contact_resort_all)
  149. // QSLContactSendFailAlertView.alert(view: self.view, contactList: self.contactList!)
  150. QSLNetwork().request(.contactMaydayAll(dict: [:])) { response in
  151. if let data = response.fetchJSONString(path: "data>fail").data(using: .utf8), let failList = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] {
  152. print(failList)
  153. if failList.count > 0 {
  154. QSLContactSendFailAlertView.alert(view: self.view, contactList: failList)
  155. gravityInstance?.track(QSLGravityConst.contact_resort_all_fail_alert)
  156. } else {
  157. self.view.toast(text: "求助消息发送成功")
  158. gravityInstance?.track(QSLGravityConst.contact_resort_all_success)
  159. }
  160. }
  161. } fail: { code, error in
  162. gravityInstance?.track(QSLGravityConst.contact_resort_all_fail)
  163. self.view.toast(text: "求助消息发送失败,请稍后重试")
  164. }
  165. }
  166. }
  167. extension QSLContactController: QSLContactCellDelegate {
  168. func resortClickAction(model: QSLContactModel) {
  169. gravityInstance?.track(QSLGravityConst.contact_resort_click)
  170. QSLAlertView.alert(view: self.view, title: "紧急求助", content: "确认向\(model.phone)发送短信求助?", isOneBtn: true, oneBtnText: "确认", oneBtnClosure: {
  171. gravityInstance?.track(QSLGravityConst.contact_resort_confirm)
  172. QSLNetwork().request(.contactMayday(dict: ["phone": model.phone])) { reponse in
  173. self.view.toast(text: "求助消息发送成功")
  174. gravityInstance?.track(QSLGravityConst.contact_resort_success)
  175. } fail: { code, error in
  176. self.view.toast(text: "求助消息发送失败,请核实手机号码")
  177. gravityInstance?.track(QSLGravityConst.contact_resort_fail)
  178. }
  179. }, closeBtnClosure: {
  180. gravityInstance?.track(QSLGravityConst.contact_resort_cancel)
  181. })
  182. }
  183. func favorClickAction(model: QSLContactModel) {
  184. QSLNetwork().request(.contactFavor(dict: ["phone": model.phone, "favor": true])) { reponse in
  185. self.view.toast(text: "修改默认联系人成功")
  186. NotificationCenter.default.post(name: QSLNotification.QSLRefreshContact, object: nil)
  187. } fail: { code, error in
  188. self.view.toast(text: "修改默认联系人失败,请稍后重试")
  189. }
  190. }
  191. func deleteClickAction(model: QSLContactModel) {
  192. gravityInstance?.track(QSLGravityConst.contact_delete)
  193. QSLAlertView.alert(view: self.view, title: "移除紧急联系人", content: "您确定要将\n\(model.phone)移除紧急联系人吗?", isOneBtn: false, firstBtnClosure: {
  194. gravityInstance?.track(QSLGravityConst.contact_delete_cancel)
  195. }, secondBtnClosure: {
  196. gravityInstance?.track(QSLGravityConst.contact_delete_confirm)
  197. QSLNetwork().request(.contactDelete(dict: ["phone": model.phone])) { reponse in
  198. self.view.toast(text: "删除联系人成功")
  199. NotificationCenter.default.post(name: QSLNotification.QSLRefreshContact, object: nil)
  200. } fail: { code, error in
  201. self.view.toast(text: "删除联系人失败,请稍后重试")
  202. }
  203. })
  204. }
  205. }
  206. extension QSLContactController {
  207. @objc func requestContactList() {
  208. QSLNetwork().request(.contactList(dict: [:])) { response in
  209. let list = response.mapArray(QSLContactModel.self, modelKey: "data>list")
  210. self.contactList = list
  211. self.contactTableView.reloadData()
  212. } fail: { code, error in
  213. self.view.toast(text: error)
  214. }
  215. }
  216. func requestAddContact(phone: String) {
  217. QSLNetwork().request(.contactCreate(dict: ["phone": phone])) { response in
  218. self.view.toast(text: "添加成功")
  219. NotificationCenter.default.post(name: QSLNotification.QSLRefreshContact, object: nil)
  220. } fail: { code, error in
  221. self.view.toast(text: error)
  222. }
  223. }
  224. }
  225. extension QSLContactController: UITableViewDelegate, UITableViewDataSource {
  226. func numberOfSections(in tableView: UITableView) -> Int {
  227. return self.contactList?.count ?? 0
  228. }
  229. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  230. return 1
  231. }
  232. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  233. let cell = tableView.dequeueReusableCell(cellType: QSLContactCell.self, cellForRowAt: indexPath)
  234. cell.delegate = self
  235. cell.selectionStyle = .none
  236. if let model = self.contactList?[indexPath.section] {
  237. cell.config(model: model)
  238. }
  239. return cell
  240. }
  241. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  242. return 112.rpx
  243. }
  244. func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  245. return 0.0001
  246. }
  247. func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
  248. return 8.rpx
  249. }
  250. }
  251. extension QSLContactController {
  252. func initView() {
  253. self.view.addSubview(bgImageView)
  254. bgImageView.snp.makeConstraints { make in
  255. make.left.top.right.equalTo(0)
  256. }
  257. self.view.addSubview(backButton)
  258. backButton.snp.makeConstraints { make in
  259. make.size.equalTo(CGSize(width: 150.rpx, height: 25.rpx))
  260. make.left.equalTo(12.rpx)
  261. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  262. }
  263. self.view.addSubview(contactIcon)
  264. contactIcon.snp.makeConstraints { make in
  265. make.size.equalTo(CGSize(width: 155.rpx, height: 126.rpx))
  266. make.centerX.equalToSuperview()
  267. make.top.equalTo(backButton.snp.bottom).offset(24.rpx)
  268. }
  269. self.view.addSubview(contactLabel)
  270. contactLabel.snp.makeConstraints { make in
  271. make.left.equalTo(20.rpx)
  272. make.right.equalTo(-20.rpx)
  273. make.top.equalTo(backButton.snp.bottom).offset(128.rpx)
  274. }
  275. self.view.addSubview(titleIcon)
  276. titleIcon.snp.makeConstraints { make in
  277. make.size.equalTo(CGSize(width: 89.rpx, height: 26.rpx))
  278. make.left.equalTo(20.rpx)
  279. make.top.equalTo(contactLabel.snp.bottom).offset(32.rpx)
  280. }
  281. self.view.addSubview(addBtn)
  282. addBtn.snp.makeConstraints { make in
  283. make.size.equalTo(CGSize(width: 90.rpx, height: 20.rpx))
  284. make.right.equalTo(-12.rpx)
  285. make.bottom.equalTo(titleIcon.snp.bottom)
  286. }
  287. self.view.addSubview(emptyAddLabel)
  288. emptyAddLabel.snp.makeConstraints { make in
  289. make.top.equalTo(addBtn.snp.bottom).offset(110.rpx)
  290. make.centerX.equalToSuperview()
  291. }
  292. self.view.addSubview(bottomView)
  293. bottomView.snp.makeConstraints { make in
  294. make.left.right.bottom.equalTo(0)
  295. make.height.equalTo(76.rpx)
  296. }
  297. bottomView.addSubview(sendBtn)
  298. sendBtn.snp.makeConstraints { make in
  299. make.size.equalTo(CGSize(width: 328.rpx, height: 44.rpx))
  300. make.center.equalToSuperview()
  301. }
  302. self.view.addSubview(contactTableView)
  303. contactTableView.snp.makeConstraints { make in
  304. make.top.equalTo(addBtn.snp.bottom).offset(13.rpx)
  305. make.left.equalTo(12.rpx)
  306. make.right.equalTo(-12.rpx)
  307. make.bottom.equalTo(bottomView.snp.top)
  308. }
  309. }
  310. }