QSLHomeController.swift 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. //
  2. // QSLHomeController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by mac on 2024/4/10.
  6. //
  7. import UIKit
  8. import SwiftyJSON
  9. import MAMapKit
  10. import AMapFoundationKit
  11. import AMapLocationKit
  12. import YYText
  13. class QSLHomeController: QSLBaseController {
  14. // 存储上次时间戳的属性
  15. private var lastActionTimestamp: TimeInterval = 0
  16. // 检查时间间隔的方法
  17. private func shouldProceedWithAction() -> Bool {
  18. let currentTimestamp = Date().timeIntervalSince1970
  19. if lastActionTimestamp == 0 || currentTimestamp - lastActionTimestamp >= 1 {
  20. lastActionTimestamp = currentTimestamp
  21. return true
  22. } else {
  23. return false
  24. }
  25. }
  26. lazy var viewModel: QSLHomeViewModel = {
  27. return QSLHomeViewModel()
  28. }()
  29. var personalModel: QSLUserModel = QSLUserModel()
  30. ///判断是不是第一次定位成功
  31. var isFirstLocatScuess : Bool = true
  32. var isFirstRequestLoc : Bool = false
  33. var isEnterSearchFriend : Bool = false
  34. // var friendList: [QSLUserModel] = [QSLUserModel]()
  35. override func viewDidLoad() {
  36. super.viewDidLoad()
  37. checkDialog()
  38. QSLTools.shared.requestShortcutItem()
  39. }
  40. func checkDialog(){
  41. if UserDefaults.standard.string(forKey: "FIRST_ENTER_LOCATION_HOMEPAGE") == nil{
  42. isFirstRequestLoc = true
  43. }
  44. dealWithMap();
  45. QSLTools.shared.isOpen = true
  46. if(QSLTools.shared.urlScheme.count > 0){
  47. if(isFirstRequestLoc){
  48. isEnterSearchFriend = true
  49. }
  50. QSLTools.shared.dealwithScheme(QSLTools.shared.urlScheme)
  51. return
  52. }
  53. //会员而且没有好友才弹出来
  54. if QSLBaseManager.shared.isVip() {
  55. QSLNetwork().request(.friendList(dict: [:])) { response in
  56. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  57. if(list.count == 0){
  58. self.showAddFriendView()
  59. }
  60. } fail: { code, error in
  61. }
  62. }else{
  63. let vc = QSLActivityVipVC()
  64. vc.modalPresentationStyle = .fullScreen
  65. self.navigationController?.pushViewController(vc, animated: false)
  66. vc.dismissHandler = {[weak self] isCancel in
  67. QSLGuideusersToCommentManager.commentShare.manageWhetherTriggerPopUpWindow(.nonMember){[weak self] in
  68. self?.showAddFriendView(hideBtnClosure: {[weak self] in
  69. DispatchQueue.main.async {
  70. self?.checkLocAgain();
  71. }
  72. })
  73. DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
  74. QSLGuideusersToCommentManager.commentShare.isClose = true
  75. }
  76. }
  77. }
  78. }
  79. }
  80. func checkLocAgain(){
  81. homeMapLocationM.startUpdatingLocation()
  82. homeMapView.showsUserLocation = true
  83. homeMapView.userTrackingMode = .follow
  84. self.onceLocation()
  85. firstEnterLocationHomepage()
  86. if(QSLBaseManager.shared.isLogin()){
  87. let memberModel = QSLBaseManager.shared.userModel.memberModel
  88. let duration = (memberModel.serverTimestamp - memberModel.endTimestamp)
  89. if(duration > 0 && memberModel.trialed) {
  90. showTrialDialog()
  91. }
  92. }
  93. }
  94. func showTrialDialog(){
  95. if let currentWindow = UIApplication.keyWindow {
  96. QSLTrialTipsAlertView.alert(view: currentWindow, clickBtnClosure: {[weak self] in
  97. QSLJumpManager.shared.pushToVip(type: .shortcut)
  98. },hideBtnClosure: {
  99. })
  100. }
  101. }
  102. override func viewWillAppear(_ animated: Bool) {
  103. super.viewWillAppear(animated)
  104. if(self.isFirstRequestLoc && self.isEnterSearchFriend){
  105. self.isEnterSearchFriend = false
  106. self.checkLocAgain();
  107. }
  108. }
  109. func showAddFriendView(hideBtnClosure: @escaping () -> () = {}){
  110. if let currentWindow = UIApplication.keyWindow {
  111. QSLHomeAddFriendView.alert(view: currentWindow, clickBtnClosure: {[weak self] in
  112. QSLJumpManager.shared.pushToAdd(type: .homealert)
  113. self?.isEnterSearchFriend = true
  114. },hideBtnClosure: {
  115. hideBtnClosure()
  116. })
  117. }
  118. }
  119. func dealWithMap(){
  120. viewModel.initUIData()
  121. setUpMap()
  122. setUpUI()
  123. loadData()
  124. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogin, object: nil)
  125. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogout, object: nil)
  126. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshFriend, object: nil)
  127. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshRequest, object: nil)
  128. NotificationCenter.default.addObserver(self, selector: #selector(requestVip), name: QSLNotification.QSLRefreshMember, object: nil)
  129. //处理第一次进入首页定位
  130. if(isFirstRequestLoc){
  131. return
  132. }
  133. firstEnterLocationHomepage()
  134. }
  135. //处理第一次进入首页定位
  136. func firstEnterLocationHomepage() {
  137. guard UserDefaults.standard.string(forKey: "FIRST_ENTER_LOCATION_HOMEPAGE") != nil else {
  138. UserDefaults.standard.set("YES", forKey: "FIRST_ENTER_LOCATION_HOMEPAGE")
  139. UserDefaults.standard.synchronize()
  140. ///第一次进入埋点
  141. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_enter_first_homepage, eventProps: ["id": 03005])
  142. return
  143. }
  144. }
  145. /// 高德地图
  146. lazy var homeMapView = {
  147. let _mapView = MAMapView()
  148. _mapView.delegate = self
  149. _mapView.minZoomLevel = 7;
  150. _mapView.maxZoomLevel = 19;
  151. _mapView.zoomLevel = 17;
  152. _mapView.showsCompass = false
  153. _mapView.showsScale = false
  154. _mapView.isRotateCameraEnabled = false
  155. if(!isFirstRequestLoc){
  156. _mapView.showsUserLocation = true
  157. _mapView.userTrackingMode = .follow
  158. }
  159. // 关闭显示精度圈
  160. let represent = MAUserLocationRepresentation()
  161. represent.showsAccuracyRing = false
  162. _mapView.update(represent)
  163. let tap = UITapGestureRecognizer(target: self, action: #selector(mapTapAction))
  164. _mapView.addGestureRecognizer(tap)
  165. return _mapView
  166. }()
  167. /// 高德地图定位
  168. lazy var homeMapLocationM = {
  169. let _homeMapLocationM = AMapLocationManager()
  170. _homeMapLocationM.delegate = self
  171. _homeMapLocationM.distanceFilter = 100
  172. _homeMapLocationM.locatingWithReGeocode = true
  173. _homeMapLocationM.desiredAccuracy = kCLLocationAccuracyHundredMeters
  174. _homeMapLocationM.locationTimeout = 2
  175. _homeMapLocationM.reGeocodeTimeout = 2
  176. _homeMapLocationM.pausesLocationUpdatesAutomatically = false
  177. _homeMapLocationM.allowsBackgroundLocationUpdates = true
  178. return _homeMapLocationM
  179. }()
  180. /// 头部定位权限弹窗
  181. lazy var homeAuthHeaderView = {
  182. let _homeAuthHeaderView = QSLHomeAuthHeaderView()
  183. _homeAuthHeaderView.addRadius(radius: 6)
  184. return _homeAuthHeaderView
  185. }()
  186. @objc func homeFriendBtnAction(){
  187. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  188. }
  189. lazy var homeFriendBtn: UIButton = {
  190. let _homeResortBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 56.rpx, height: 56.rpx))
  191. _homeResortBtn.image(UIImage(named: "home_find_friend"))
  192. _homeResortBtn.addTarget(self, action: #selector(homeFriendBtnAction), for: .touchUpInside)
  193. return _homeResortBtn
  194. }()
  195. /// 定位按钮
  196. lazy var homeLocateBtnView = {
  197. let _homeLocateBtnView = UIView()
  198. _homeLocateBtnView.addRadius(radius: 6)
  199. _homeLocateBtnView.effectViewWithAlpha(alpha: 1, size: CGSize(width: 40, height: 40), style: .light)
  200. return _homeLocateBtnView
  201. }()
  202. lazy var homeLocateBtn = {
  203. let _homeLocateBtn = UIButton(type: .custom)
  204. _homeLocateBtn.image(UIImage(named: "home_btn_locate"))
  205. return _homeLocateBtn
  206. }()
  207. /// 无好友和未登录时的状态
  208. lazy var homeEmptyView: QSLHomeEmptyView = {
  209. let _homeEmptyView = QSLHomeEmptyView()
  210. _homeEmptyView.delegate = self
  211. _homeEmptyView.isHidden = true
  212. return _homeEmptyView
  213. }()
  214. lazy var homeFriendView: QSLHomeFriendView = {
  215. let topHeight = QSLConst.qsl_kStatusBarFrameH
  216. let view = QSLHomeFriendView(frame: CGRect(x: 0, y: QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH, width: QSLConst.qsl_kScreenW, height: QSLConst.qsl_kScreenH - topHeight))
  217. view.scrollTopHeight = topHeight - 40
  218. view.delegate = self
  219. return view
  220. }()
  221. }
  222. // MARK: - 网络请求等
  223. extension QSLHomeController {
  224. @objc func loadData() {
  225. // viewModel.refreshDataSoure(complete: { [unowned self] in
  226. // self.homeFriendView.viewModel = self.viewModel
  227. // let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  228. // homeFriendView.scrollCenterHeight = friViewTopY
  229. // homeFriendView.snp.updateConstraints { make in
  230. // make.top.equalTo(friViewTopY)
  231. // }
  232. // })
  233. if(!isFirstRequestLoc){
  234. self.onceLocation()
  235. }
  236. if QSLBaseManager.shared.isLogin() {
  237. self.initSocket()
  238. } else {
  239. self.deposeSocket()
  240. }
  241. requestFriendList()
  242. requestVip()
  243. }
  244. // 请求好友列表
  245. @objc func requestFriendList() {
  246. self.homeMapView.removeAnnotations(self.homeMapView.annotations)
  247. viewModel.friendList.removeAll()
  248. viewModel.friendLocationList.removeAll()
  249. viewModel.friendList.append(QSLBaseManager.shared.userModel)
  250. QSLNetwork().request(.friendList(dict: [:])) { response in
  251. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  252. self.viewModel.friendList.append(contentsOf: list)
  253. self.homeFriendView.viewModel = self.viewModel
  254. for model in list {
  255. let pointAnnotation = MAPointAnnotation()
  256. let loc = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  257. pointAnnotation.coordinate = loc
  258. if model.remark.count > 0 {
  259. pointAnnotation.title = model.remark
  260. } else {
  261. pointAnnotation.title = model.phone
  262. }
  263. pointAnnotation.subtitle = "300"
  264. let pointModel = QSLMapPointModel()
  265. pointModel.userId = model.userId
  266. pointModel.pointAnnotation = pointAnnotation
  267. self.viewModel.friendLocationList.append(pointModel)
  268. if QSLBaseManager.shared.isVip() && !model.blockedMe {
  269. self.homeMapView.addAnnotation(pointAnnotation)
  270. }
  271. }
  272. } fail: { code, error in
  273. self.homeFriendView.viewModel = self.viewModel
  274. }
  275. }
  276. // 请求vip信息
  277. @objc func requestVip() {
  278. QSLNetwork().request(.userMember(dict: [:])) { response in
  279. let memberModel = response.mapObject(QSLMemberModel.self, modelKey: "data")
  280. QSLBaseManager.shared.userModel.memberModel = memberModel
  281. if memberModel.expired {
  282. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  283. } else {
  284. QSLBaseManager.shared.saveVipExpiredTime(time: memberModel.endTimestamp)
  285. }
  286. QSLBaseManager.shared.saveUserId(id: memberModel.userId)
  287. if(self.shouldProceedWithAction()){
  288. QSLTools.shared.requestShortcutItem()
  289. }
  290. // NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  291. } fail: { code, error in
  292. }
  293. }
  294. }
  295. // MARK: - 设置地图相关方法
  296. extension QSLHomeController: MAMapViewDelegate, AMapLocationManagerDelegate {
  297. // 初始化高德地图设置
  298. func setUpMap() {
  299. AMapServices.shared().enableHTTPS = true
  300. AMapLocationManager.updatePrivacyShow(.didShow, privacyInfo: .didContain)
  301. AMapLocationManager.updatePrivacyAgree(.didAgree)
  302. homeMapLocationM.locatingWithReGeocode = true
  303. if(!isFirstRequestLoc){
  304. homeMapLocationM.startUpdatingLocation()
  305. }
  306. }
  307. // 申请地图定位权限
  308. func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
  309. locationManager.requestWhenInUseAuthorization()
  310. }
  311. // 地图触摸事件
  312. @objc func mapTapAction() {
  313. if self.homeFriendView.scrollLocation != .ScrollBottom {
  314. self.homeFriendView.scrollToLocation(type: .ScrollBottom)
  315. }
  316. }
  317. // 获取一次性定位
  318. func onceLocation() {
  319. // 先停止持续定位
  320. self.homeMapLocationM.stopUpdatingLocation()
  321. self.homeMapLocationM.requestLocation(withReGeocode: true) { location, regeocode, error in
  322. if error != nil {
  323. self.personalModel = QSLBaseManager.shared.userModel
  324. // 获取电话和名字
  325. // self.personalModel.phone = QSLBaseManager.shared.userModel.phone
  326. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  327. if !QSLBaseManager.shared.isLogin() {
  328. name = "自己"
  329. }
  330. name = "自己"
  331. self.personalModel.remark = name
  332. // 地址
  333. self.personalModel.location.addr = "请先开启位置权限"
  334. QSLBaseManager.shared.updateUser(model: self.personalModel)
  335. if self.viewModel.friendList.isEmpty {
  336. self.viewModel.friendList.append(self.personalModel)
  337. } else {
  338. self.viewModel.friendList[0] = self.personalModel
  339. }
  340. self.homeFriendView.viewModel = self.viewModel
  341. self.homeMapLocationM.startUpdatingLocation()
  342. return
  343. }
  344. self.personalModel = QSLBaseManager.shared.userModel
  345. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  346. if !QSLBaseManager.shared.isLogin() {
  347. name = "自己"
  348. }
  349. name = "自己"
  350. self.personalModel.remark = name
  351. self.personalModel.location.addr = regeocode?.formattedAddress ?? "未知"
  352. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  353. if let location = location {
  354. // 地图居中
  355. self.homeMapView.setCenter(location.coordinate, animated: true)
  356. self.homeFriendView.scrollLocation = .ScrollCenter
  357. self.personalModel.location.lat = location.coordinate.latitude
  358. self.personalModel.location.lng = location.coordinate.longitude
  359. // 速度
  360. self.personalModel.location.speed = location.speed >= 0 ? location.speed : 0
  361. // 朝向
  362. self.personalModel.location.bearing = location.course >= 0 ? location.course : 0
  363. }
  364. QSLBaseManager.shared.updateUser(model: self.personalModel)
  365. if QSLBaseManager.shared.isLogin() {
  366. let locationData = self.personalModel.location
  367. let addr = locationData.addr
  368. if addr != "请先开启位置权限" {
  369. self.sendSocket()
  370. }
  371. }
  372. if self.viewModel.friendList.isEmpty {
  373. self.viewModel.friendList.append(self.personalModel)
  374. } else {
  375. self.viewModel.friendList[0] = self.personalModel
  376. }
  377. print("location: \(String(describing: location))")
  378. if let regeocode = regeocode {
  379. print("reGeocode: \(regeocode)")
  380. }
  381. self.homeFriendView.viewModel = self.viewModel
  382. self.homeMapLocationM.startUpdatingLocation()
  383. }
  384. }
  385. // 持续定位
  386. func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
  387. if self.isFirstLocatScuess {
  388. self.isFirstLocatScuess = false
  389. //始终允许定位成功
  390. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_success_always, eventProps: ["id": 03003])
  391. }
  392. // 获取电话和名字
  393. self.personalModel = QSLBaseManager.shared.userModel
  394. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  395. if !QSLBaseManager.shared.isLogin() {
  396. name = "自己"
  397. }
  398. name = "自己"
  399. self.personalModel.remark = name
  400. // 时间戳
  401. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  402. // 经纬度
  403. self.personalModel.location.lat = location.coordinate.latitude
  404. self.personalModel.location.lng = location.coordinate.longitude
  405. // 速度
  406. if location.speed >= 0 {
  407. self.personalModel.location.speed = location.speed
  408. } else {
  409. self.personalModel.location.speed = 0
  410. }
  411. // 朝向
  412. if location.course >= 0 {
  413. self.personalModel.location.bearing = location.course
  414. } else {
  415. self.personalModel.location.bearing = 0
  416. }
  417. // 打印位置信息
  418. print("location: {lat: \(location.coordinate.latitude); lon: \(location.coordinate.longitude); accuracy: \(location.horizontalAccuracy)}")
  419. // 逆地理编码处理
  420. if let reGeocode = reGeocode {
  421. print("reGeocode: \(reGeocode)")
  422. self.personalModel.location.addr = reGeocode.formattedAddress
  423. } else {
  424. self.personalModel.location.addr = "请先开启位置权限"
  425. }
  426. // 保存到模块
  427. QSLBaseManager.shared.updateUser(model: self.personalModel)
  428. // 更新好友列表
  429. if self.viewModel.friendList.isEmpty {
  430. self.viewModel.friendList.append(self.personalModel)
  431. } else {
  432. self.viewModel.friendList[0] = self.personalModel
  433. }
  434. self.homeFriendView.viewModel = self.viewModel
  435. // 更新UI
  436. // self.updateHomeUI()
  437. // 如果已登录,发送定位信息
  438. if QSLBaseManager.shared.isLogin() {
  439. let locationData = self.personalModel.location
  440. let addr = locationData.addr
  441. if addr != "请先开启位置权限" {
  442. self.sendSocket()
  443. }
  444. }
  445. }
  446. func mapView(_ mapView: MAMapView!, viewFor annotation: (any MAAnnotation)!) -> MAAnnotationView! {
  447. // 处理用户位置的标注
  448. if annotation is MAUserLocation {
  449. let reuseIdentifier = "UserAnotation"
  450. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  451. if annotationView == nil {
  452. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  453. }
  454. let name = "我"
  455. annotationView?.title = name
  456. annotationView?.isEnabled = false
  457. annotationView?.image = UIImage(named: "home_mine_anno")
  458. annotationView?.canShowCallout = false
  459. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  460. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  461. annotationView?.zIndex = 360
  462. annotationView?.isSelected = true
  463. return annotationView
  464. }
  465. // 处理普通点标注
  466. if annotation is MAPointAnnotation {
  467. let reuseIdentifier = "OtherAnnotation"
  468. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  469. if annotationView == nil {
  470. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  471. annotationView?.title = annotation.title
  472. }
  473. if let subtitle = annotation.subtitle as? Int {
  474. annotationView?.zIndex = subtitle
  475. }
  476. annotationView?.isEnabled = false
  477. annotationView?.image = UIImage(named: "home_mine_anno")
  478. annotationView?.canShowCallout = false
  479. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  480. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  481. annotationView?.isSelected = true
  482. return annotationView
  483. }
  484. return nil
  485. }
  486. //@brief 定位权限状态改变时回调函数。注意:iOS13及之前版本回调
  487. // 高德地图权限变化回调
  488. func amapLocationManager(_ manager: AMapLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
  489. //print("高德地图定位权限变化: \(status.rawValue)")
  490. switch status {
  491. case .authorizedAlways, .authorizedWhenInUse:
  492. //print("定位权限已授权")
  493. //支付成功埋点
  494. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03001])
  495. case .denied:
  496. //print("定位权限被拒绝")
  497. //拒绝定位权限
  498. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03002])
  499. default:
  500. break
  501. }
  502. }
  503. // 系统定位权限变化回调
  504. func amapLocationManager(_ manager: AMapLocationManager, locationManagerDidChangeAuthorization locationManager: CLLocationManager) {
  505. if #available(iOS 14.0, *) {
  506. let status = locationManager.authorizationStatus
  507. // 统一处理权限变化
  508. amapLocationManager(manager, didChangeAuthorization: status)
  509. // if(status != .notDetermined){
  510. // QSLTools.shared.requestNotificationPermission()
  511. // }
  512. //print("系统定位权限变化: \(status.rawValue)")
  513. } else {
  514. // Fallback on earlier versions
  515. }
  516. }
  517. // 定位结果回调
  518. func amapLocationManager(_ manager: AMapLocationManager, didFailWithError error: Error) {
  519. print("定位失败: \(error.localizedDescription)")
  520. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_fail_always, eventProps: ["id": 03004])
  521. }
  522. }
  523. // MARK: - 设置WebSocket
  524. extension QSLHomeController: QSLSocketManagerDelegate {
  525. // 初始化
  526. func initSocket() {
  527. QSLSocketManager.shared.urlString = "\(QSLApi.prodWSUrl)/websocket/\(QSLBaseManager.shared.userModel.authToken)"
  528. QSLSocketManager.shared.connect()
  529. QSLSocketManager.shared.delegate = self
  530. }
  531. // 关闭socket
  532. func deposeSocket() {
  533. QSLSocketManager.shared.urlString = ""
  534. QSLSocketManager.shared.close()
  535. QSLSocketManager.shared.delegate = nil
  536. }
  537. // 发送socket信息
  538. func sendSocket() {
  539. var message = QSLMapMessageModel()
  540. message.cmd = "u.location"
  541. var location = QSLMapTrackModel()
  542. location.lat = self.personalModel.location.lat
  543. location.lng = self.personalModel.location.lng
  544. location.addr = self.personalModel.location.addr
  545. location.speed = self.personalModel.location.speed
  546. location.bearing = self.personalModel.location.bearing
  547. location.timestamp = Int(Date.milliStamp) ?? 0
  548. message.body = location.toJSONString()
  549. QSLSocketManager.shared.sendMessage(message.toJSONString())
  550. }
  551. // 接收到消息
  552. func socketDidReceiveMessage(with string: String) {
  553. let locationModel = QSLMapMessageModel.mapModel(from: string)
  554. if let data = locationModel.body.data(using: .utf8), let list = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [QSLMapTrackModel] {
  555. if locationModel.cmd == "d.location.batch" {
  556. for model in list {
  557. var isBlockedMe = false
  558. for var user in viewModel.friendList {
  559. if model.userId == user.friendId {
  560. user.location = model
  561. isBlockedMe = user.blockedMe
  562. }
  563. }
  564. if !isBlockedMe && QSLBaseManager.shared.isVip() {
  565. for location in viewModel.friendLocationList {
  566. if model.userId == location.userId {
  567. let annotation = MAPointAnnotation()
  568. let cll2d = CLLocationCoordinate2D(latitude: model.lat, longitude: model.lng)
  569. annotation.coordinate = cll2d
  570. location.pointAnnotation = annotation
  571. self.homeMapView.addAnnotation(location.pointAnnotation)
  572. }
  573. }
  574. }
  575. }
  576. self.homeFriendView.viewModel = self.viewModel
  577. }
  578. }
  579. }
  580. }
  581. // MARK: - 设置界面代理方法
  582. extension QSLHomeController: QSLHomeEmptyViewDelegate, QSLHomeFriendViewDelegate {
  583. func viewDidScroll() {
  584. switch self.homeFriendView.scrollLocation {
  585. case .ScrollTop:
  586. self.homeFriendView.snp.updateConstraints { make in
  587. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH - 40.rpx)
  588. }
  589. break
  590. case .ScrollCenter:
  591. self.homeFriendView.snp.updateConstraints { make in
  592. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kStatusBarFrameH)
  593. }
  594. break
  595. case .ScrollBottom:
  596. self.homeFriendView.snp.updateConstraints { make in
  597. if(QSLBaseManager.shared.isVip()){
  598. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx)
  599. }else{
  600. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx - 48.rpx)
  601. }
  602. }
  603. break
  604. default:
  605. break
  606. }
  607. }
  608. func addFriendAction(isSmall: Bool) {
  609. if isSmall {
  610. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  611. } else {
  612. QSLJumpManager.shared.pushToAdd(type: .homebig)
  613. }
  614. }
  615. func refreshBtnAction() {
  616. QSEventHandle.eventPush(eventName: QSLGravityConst.home_locate)
  617. self.loadData()
  618. }
  619. // 轨迹
  620. func routeBtnAction(model: QSLUserModel) {
  621. if QSLBaseManager.shared.isVip() {
  622. if !QSLBaseManager.shared.isLogin() {
  623. QSLJumpManager.shared.pushToLogin(type: .contact)
  624. return
  625. }
  626. }else{
  627. QSLJumpManager.shared.pushToVip(type: .contact)
  628. return
  629. }
  630. QSLJumpManager.shared.pushToRoad(type: .home, model: model)
  631. }
  632. // 点击列表的定位按钮
  633. func locateBtnAction(model: QSLUserModel) {
  634. if !QSLBaseManager.shared.isVip() {
  635. self.view.toast(text: "请先开通会员")
  636. return
  637. }
  638. if model.blockedMe {
  639. return
  640. }
  641. let location = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  642. self.homeMapView.setCenter(location, animated: true)
  643. for point in self.viewModel.friendLocationList {
  644. if point.userId == model.friendId {
  645. self.homeMapView.removeAnnotation(point.pointAnnotation)
  646. point.pointAnnotation?.subtitle = "350"
  647. self.homeMapView.addAnnotation(point.pointAnnotation)
  648. }
  649. }
  650. }
  651. func emptyFriPhoneViewClick() {
  652. if let vc = self.tabBarController {
  653. QSLFriendAddAlertView.show(vc: vc) {
  654. }
  655. }
  656. }
  657. func homeFriPhoneViewClick() {
  658. if let vc = self.tabBarController {
  659. QSLFriendAddAlertView.show(vc: vc) {
  660. }
  661. }
  662. }
  663. }
  664. // MARK: - 设置UI相关方法
  665. extension QSLHomeController {
  666. // 设置基础UI
  667. func setUpUI() {
  668. view.addSubview(homeMapView)
  669. homeMapView.snp.makeConstraints { make in
  670. make.edges.equalTo(0)
  671. }
  672. view.addSubview(homeFriendBtn)
  673. homeFriendBtn.snp.makeConstraints { make in
  674. make.size.equalTo(CGSize(width: 56.rpx, height: 56.rpx))
  675. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH + 28.rpx)
  676. make.right.equalTo(-2.rpx)
  677. }
  678. //
  679. // view.addSubview(homeLocateBtnView)
  680. // homeLocateBtnView.snp.makeConstraints { make in
  681. // make.size.equalTo(CGSize(width: 40, height: 40))
  682. // make.top.equalTo(self.homeButtonsView.snp.bottom).offset(16)
  683. // make.right.equalTo(QSLHomeViewModel.UX.viewRight)
  684. // }
  685. view.addSubview(homeFriendView)
  686. homeFriendView.snp.makeConstraints { make in
  687. make.left.right.equalTo(0)
  688. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH)
  689. make.height.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH)
  690. }
  691. let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  692. homeFriendView.scrollCenterHeight = friViewTopY
  693. homeFriendView.snp.updateConstraints { make in
  694. make.top.equalTo(friViewTopY)
  695. }
  696. }
  697. }