QSLVipController.swift 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. //
  2. // QSLVipController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2024/11/27.
  6. //
  7. import UIKit
  8. import YYText
  9. enum QSLVipJumpType: Int {
  10. case homeRoad // 定位查看轨迹
  11. case add // 添加好友
  12. case friendRoad // 好友列表查看轨迹
  13. case contact // 添加紧急联系人
  14. case mine //
  15. }
  16. class QSLVipController: QSLBaseController {
  17. var type: QSLVipJumpType?
  18. var goodList: [QSLGoodModel] = [QSLGoodModel]()
  19. var selectGood: QSLGoodModel? {
  20. didSet {
  21. updateSelectGoodUI()
  22. }
  23. }
  24. lazy var vipBg: UIImageView = {
  25. let imageView = UIImageView()
  26. imageView.image = UIImage(named: "vip_bg")
  27. return imageView
  28. }()
  29. lazy var backButton: UIButton = {
  30. let button = UIButton()
  31. button.image(UIImage(named: "public_back_btn_white"))
  32. button.title("会员中心")
  33. button.mediumFont(17)
  34. button.textColor(.white)
  35. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  36. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  37. return button
  38. }()
  39. lazy var peopleCountView: UIView = {
  40. let view = UIView()
  41. view.layer.cornerRadius = 12.rpx
  42. view.layer.borderColor = UIColor.white.withAlphaComponent(0.16).cgColor
  43. view.layer.borderWidth = 1.rpx
  44. return view
  45. }()
  46. lazy var peopleAvatarImageView: UIImageView = {
  47. let imageView = UIImageView()
  48. imageView.image = UIImage(named: "vip_avatars_icon")
  49. return imageView
  50. }()
  51. lazy var peopleCountLabel: UILabel = {
  52. let label = UILabel()
  53. label.text("1456488人 已开通VIP")
  54. label.color("#FFE6C0")
  55. label.font(12)
  56. return label
  57. }()
  58. lazy var scrollView: UIScrollView = {
  59. let scrollView = UIScrollView()
  60. // scrollView.delegate = self
  61. scrollView.bounces = false
  62. scrollView.showsVerticalScrollIndicator = false
  63. scrollView.contentInsetAdjustmentBehavior = .never
  64. return scrollView
  65. }()
  66. lazy var cardBannerImageView: UIImageView = {
  67. let imageView = UIImageView()
  68. imageView.image = UIImage(named: "vip_banner_card")
  69. return imageView
  70. }()
  71. lazy var vipTimeLabel: UILabel = {
  72. let label = UILabel()
  73. label.text("升级VIP会员,解锁全部功能")
  74. label.font(13)
  75. label.textColor = .hexStringColor(hexString: "#AF7655")
  76. return label
  77. }()
  78. lazy var funcBannerImageView: UIImageView = {
  79. let imageView = UIImageView()
  80. imageView.image = UIImage(named: "vip_banner_func")
  81. return imageView
  82. }()
  83. lazy var mainView: UIView = {
  84. let view = UIView()
  85. view.backgroundColor = QSLColor.backGroundColor
  86. view.addRadius(radius: 12.rpx)
  87. return view
  88. }()
  89. lazy var goodsBgView: UIView = {
  90. let view = UIView()
  91. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FFF8F2"), color2: .hexStringColor(hexString: "#FFFFFF"), width: QSLConst.qsl_kScreenW, height: 255.rpx, direction: .vertical)
  92. return view
  93. }()
  94. lazy var vipGoodsTitleIcon: UIImageView = {
  95. let imageView = UIImageView()
  96. imageView.image = UIImage(named: "vip_title_icon")
  97. return imageView
  98. }()
  99. lazy var resumeBtn: UIButton = {
  100. let button = UIButton()
  101. button.title("恢复购买")
  102. button.setTitleColor(.hexStringColor(hexString: "#000000").withAlphaComponent(0.5), for: .normal)
  103. button.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: .medium)
  104. button.image(UIImage(named: "vip_resume_btn"))
  105. button.setImageTitleLayout(.imgLeft, spacing: 2.rpx)
  106. button.addTarget(self, action: #selector(resumeBtnAction), for: .touchUpInside)
  107. return button
  108. }()
  109. lazy var goodsCollectionView: UICollectionView = {
  110. let layout = UICollectionViewFlowLayout()
  111. layout.minimumLineSpacing = 0
  112. layout.scrollDirection = .horizontal
  113. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  114. collectionView.backgroundColor = .clear
  115. collectionView.dataSource = self
  116. collectionView.delegate = self
  117. collectionView.showsHorizontalScrollIndicator = false
  118. collectionView.bounces = false
  119. collectionView.register(cellClass: QSLVipGoodCollectionViewCell.self)
  120. return collectionView
  121. }()
  122. lazy var selectBtn: UIButton = {
  123. let btn = UIButton()
  124. btn.image(UIImage(named: "public_select_btn_false"), .normal)
  125. btn.image(UIImage(named: "public_select_btn_true"), .selected)
  126. btn.addTarget(self, action: #selector(selectBtnAction), for: .touchUpInside)
  127. return btn
  128. }()
  129. lazy var serviceLabel: YYLabel = {
  130. let label = YYLabel()
  131. let attr = NSMutableAttributedString()
  132. let firstAttr = NSMutableAttributedString(string: "购买即同意")
  133. firstAttr.font(12)
  134. firstAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  135. attr.append(firstAttr)
  136. let blankAttr = NSMutableAttributedString(string: " ")
  137. blankAttr.font(12)
  138. attr.append(blankAttr)
  139. let privacyHL = YYTextHighlight()
  140. var privacyStr = "《隐私权政策》"
  141. let privacyText = NSMutableAttributedString(string: privacyStr)
  142. privacyText.font(12)
  143. privacyText.color(.hexStringColor(hexString: "#E7B983"))
  144. privacyText.yy_setTextHighlight(privacyHL, range: NSRange(location: 0, length: privacyStr.count))
  145. privacyHL.tapAction = { [weak self] containerView, text, range, rect in
  146. self?.privacyAction()
  147. }
  148. attr.append(privacyText)
  149. attr.append(blankAttr)
  150. let serviceHL = YYTextHighlight()
  151. var serviceStr = "《用户协议》"
  152. let serviceText = NSMutableAttributedString(string: serviceStr)
  153. serviceText.font(12)
  154. serviceText.color(.hexStringColor(hexString: "#E7B983"))
  155. serviceText.yy_setTextHighlight(serviceHL, range: NSRange(location: 0, length: serviceStr.count))
  156. serviceHL.tapAction = { [weak self] containerView, text, range, rect in
  157. self?.serviceAction()
  158. }
  159. attr.append(serviceText)
  160. attr.append(blankAttr)
  161. let andAttr = NSMutableAttributedString(string: "和")
  162. andAttr.font(12)
  163. andAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  164. attr.append(andAttr)
  165. attr.append(blankAttr)
  166. let subcribeHL = YYTextHighlight()
  167. var subcribeStr = "《续订说明》"
  168. let subcribeText = NSMutableAttributedString(string: subcribeStr)
  169. subcribeText.font(12)
  170. subcribeText.color(.hexStringColor(hexString: "#E7B983"))
  171. subcribeText.yy_setTextHighlight(subcribeHL, range: NSRange(location: 0, length: subcribeStr.count))
  172. subcribeHL.tapAction = { [weak self] containerView, text, range, rect in
  173. self?.subscibeAction()
  174. }
  175. attr.append(subcribeText)
  176. label.attributedText = attr
  177. return label
  178. }()
  179. lazy var commentView: UIView = {
  180. let view = UIView()
  181. view.backgroundColor = .white
  182. return view
  183. }()
  184. lazy var commentTitleIcon: UIImageView = {
  185. let imageView = UIImageView()
  186. imageView.image = UIImage(named: "vip_comment_title_icon")
  187. return imageView
  188. }()
  189. lazy var comment1: QSLVipCommentCellView = {
  190. let view = QSLVipCommentCellView()
  191. view.config(name: "用户189****7913", comment: "上班没时间,远程遛娃,非常方便很好用。")
  192. return view
  193. }()
  194. lazy var comment2: QSLVipCommentCellView = {
  195. let view = QSLVipCommentCellView()
  196. view.config(name: "用户189****7913", comment: "用了之后,才发现真的可以找到他。")
  197. return view
  198. }()
  199. lazy var comment3: QSLVipCommentCellView = {
  200. let view = QSLVipCommentCellView()
  201. view.config(name: "用户189****7913", comment: "轨迹很准,一目了然,奶奶出门遇到危险直接一键报警,我就收到信息了")
  202. return view
  203. }()
  204. lazy var tipTitleLabel: UILabel = {
  205. let label = UILabel()
  206. label.text("温馨提示")
  207. label.font(12)
  208. label.textColor = .hexStringColor(hexString: "#000000").withAlphaComponent(0.8)
  209. return label
  210. }()
  211. lazy var tipContentLabel: UILabel = {
  212. let label = UILabel()
  213. label.numberOfLines = 0
  214. label.text("1 订阅后会从您的iTunes账户中扣除相关费用。如需取消续订,请在当前订阅周期结束前,至少24小时内通过手机“账户设置”的订阅管理关闭自动续费功能。\n2 未成年人请在监护者的陪同下进行购买\n3 购买后不支持退款,请仔细审阅《隐私权政策》《用户协议》和《续订说明》")
  215. label.font(10)
  216. label.textColor = .hexStringColor(hexString: "#000000").withAlphaComponent(0.6)
  217. label.changeLineSpace(space: 5)
  218. return label
  219. }()
  220. lazy var bottomView: UIView = {
  221. let view = UIView()
  222. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#00434E"), color2: .hexStringColor(hexString: "#0E5E61"), width: QSLConst.qsl_kScreenW - 24.rpx, height: 50.rpx, direction: .horizontal)
  223. view.addRadius(radius: 25.rpx)
  224. return view
  225. }()
  226. lazy var unlockBtn: UIButton = {
  227. let btn = UIButton()
  228. btn.setBackgroundImage(UIImage(named: "vip_unlock_btn_bg"), for: .normal)
  229. btn.title("立即解锁")
  230. btn.textColor(.hexStringColor(hexString: "#9B3800"))
  231. btn.mediumFont(18)
  232. btn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 30.rpx, bottom: 0, right: 0)
  233. btn.addTarget(self, action: #selector(unlockBtnAction), for: .touchUpInside)
  234. return btn
  235. }()
  236. lazy var priceIconLabel: UILabel = {
  237. let label = UILabel()
  238. label.text("¥")
  239. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  240. label.font(14)
  241. return label
  242. }()
  243. lazy var priceLabel: UILabel = {
  244. let label = UILabel()
  245. label.text("168")
  246. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  247. label.font(24)
  248. return label
  249. }()
  250. lazy var goodTypeLabel: UILabel = {
  251. let label = UILabel()
  252. label.text("/")
  253. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  254. label.font(12)
  255. return label
  256. }()
  257. lazy var goodOriginalPriceLabel: UILabel = {
  258. let label = UILabel()
  259. label.text("原价228")
  260. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  261. label.font(12)
  262. label.centerLineText(lineValue: 1, underlineColor: .hexStringColor(hexString: "#FFF8EF"))
  263. return label
  264. }()
  265. override func viewDidLoad() {
  266. super.viewDidLoad()
  267. initializeView()
  268. updateUI()
  269. requestItemList()
  270. calculateBuyCount()
  271. if let type = self.type {
  272. switch type {
  273. case .homeRoad:
  274. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1001])
  275. case .add:
  276. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1002])
  277. case .friendRoad:
  278. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1003])
  279. case .contact:
  280. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1004])
  281. case .mine:
  282. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1006])
  283. }
  284. }
  285. }
  286. }
  287. extension QSLVipController {
  288. @objc func privacyAction() {
  289. let vc = QSLWebViewController()
  290. vc.webUrl = QSLConfig.AppPrivacyAgreementLink
  291. vc.title = "隐私政策"
  292. self.navigationController?.pushViewController(vc, animated: true)
  293. }
  294. @objc func serviceAction() {
  295. let vc = QSLWebViewController()
  296. vc.webUrl = QSLConfig.AppServiceAgreementLink
  297. vc.title = "服务协议"
  298. self.navigationController?.pushViewController(vc, animated: true)
  299. }
  300. @objc func subscibeAction() {
  301. let vc = QSLWebViewController()
  302. vc.webUrl = QSLConfig.AppSubscibeAgreementLink
  303. vc.title = "续订说明"
  304. self.navigationController?.pushViewController(vc, animated: true)
  305. }
  306. @objc func selectBtnAction() {
  307. selectBtn.isSelected = !selectBtn.isSelected
  308. }
  309. // 恢复按钮点击
  310. @objc func resumeBtnAction() {
  311. let memberModel = QSLBaseManager.shared.userModel.memberModel
  312. let expired = memberModel.expired
  313. if !expired {
  314. QSLLoading.success(text: "您已经在订阅中,无需恢复")
  315. return
  316. }
  317. QSLLoading.show()
  318. QSLVipManager.shared.restoreAction { isSuccess in
  319. QSLVipManager.shared.isPaying = false
  320. if isSuccess {
  321. QSLNetwork().request(.userMember(dict: [:])) { response in
  322. let model = response.mapObject(QSLMemberModel.self, modelKey: "data")
  323. QSLBaseManager.shared.userModel.memberModel = model
  324. if model.expired {
  325. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  326. } else {
  327. QSLBaseManager.shared.saveVipExpiredTime(time: model.endTimestamp)
  328. }
  329. QSLBaseManager.shared.saveUserId(id: model.userId)
  330. if model.endTimestamp > memberModel.endTimestamp {
  331. QSLLoading.success(text: "恢复成功")
  332. // 支付成功通知
  333. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  334. self.navigationController?.popViewController(animated: true)
  335. }
  336. } else {
  337. QSLLoading.error(text: "没有可供恢复的订阅")
  338. }
  339. } fail: { code, error in
  340. QSLLoading.error(text: "没有可供恢复的订阅")
  341. }
  342. } else {
  343. QSLLoading.error(text: "没有可供恢复的订阅")
  344. }
  345. }
  346. }
  347. @objc func unlockBtnAction() {
  348. switch self.selectGood?.level {
  349. case 100 :
  350. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1006])
  351. break
  352. case 700:
  353. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1005])
  354. break;
  355. case 3100:
  356. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1004])
  357. break;
  358. case 9200:
  359. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1003])
  360. break;
  361. case 36600:
  362. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1002])
  363. break;
  364. case 3660000:
  365. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1001])
  366. break;
  367. default:
  368. break;
  369. }
  370. if !selectBtn.isSelected {
  371. self.view.toast(text: "请先同意《隐私权政策》和《用户协议》")
  372. return
  373. }
  374. let memberModel = QSLBaseManager.shared.userModel.memberModel
  375. if let subscriptionExpired = memberModel.subscriptionExpired, !subscriptionExpired {
  376. self.view.toast(text: "你已经订阅了")
  377. return
  378. }
  379. if goodList.count > 0, let selectGood = self.selectGood {
  380. QSLLoading.show()
  381. QSLVipManager.shared.startPay(goods: selectGood) { status, outTradeNo in
  382. QSLVipManager.shared.isPaying = false
  383. if status == .success {
  384. QSLLoading.success(text: "支付成功")
  385. // NSLocalizedString("Payment successful", comment: "支付成功")
  386. // if let payType = self.payType {
  387. // geInstance?.track(HolaGravityConst.vip_open_success, properties: ["id": payType])
  388. //
  389. // if payType == 1004 {
  390. // geInstance?.track(HolaGravityConst.vip_alert_pay, properties: ["id": 1002])
  391. // }
  392. // }
  393. // let val: Float = 0.1
  394. // HolaSaManager.shared.addEventAttribution(eventDict: ["event_name": "pay", "event_val": val])
  395. // 引力传递支付事件
  396. if let selectGood = self.selectGood {
  397. gravityInstance?.trackPayEvent(withAmount: Int32(selectGood.amount), withPayType: "CNY", withOrderId: outTradeNo, withPayReason: selectGood.name, withPayMethod: "apple")
  398. }
  399. if let type = self.type {
  400. switch type {
  401. case .homeRoad:
  402. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1001])
  403. case .add:
  404. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1002])
  405. case .friendRoad:
  406. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1003])
  407. case .contact:
  408. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1004])
  409. case .mine:
  410. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1006])
  411. }
  412. }
  413. switch self.selectGood?.level {
  414. case 100 :
  415. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 1])
  416. break
  417. case 700:
  418. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 5])
  419. break;
  420. case 3100:
  421. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 9])
  422. break;
  423. case 9200:
  424. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 13])
  425. break;
  426. case 36600:
  427. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 17])
  428. break;
  429. case 3660000:
  430. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 21])
  431. break;
  432. default:
  433. break;
  434. }
  435. DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
  436. self.navigationController?.popViewController(animated: true)
  437. NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  438. }
  439. } else if status == .cancel {
  440. QSLLoading.error(text: "支付取消")
  441. } else if status == .fail {
  442. gravityInstance?.track(QSLGravityConst.vip_fail)
  443. QSLLoading.error(text: "支付失败")
  444. } else if status == .searchFail {
  445. QSLLoading.error(text: "查询订单失败,请稍后重试")
  446. }
  447. }
  448. }
  449. }
  450. }
  451. extension QSLVipController {
  452. // 请求商品列表
  453. func requestItemList() {
  454. QSLNetwork().request(.vipItemList(dict: ["itemListType": 2])) { response in
  455. let list = response.mapArray(QSLGoodModel.self, modelKey: "data>list")
  456. self.goodList = list
  457. if self.goodList.count > 0 {
  458. self.goodList[0].isSelect = true
  459. self.selectGood = self.goodList[0]
  460. }
  461. self.goodsCollectionView.reloadData()
  462. } fail: { code, error in
  463. self.view.toast(text: "加载商品列表失败")
  464. }
  465. }
  466. // 计算购买人数
  467. func calculateBuyCount() {
  468. var num = 145883
  469. if let localNum = UserDefaults.standard.value(forKey: QSLConfig.user_default_local_buy_count) as? Int {
  470. num = localNum
  471. }
  472. let randomAddCount = Int.random(in: 1...10)
  473. num = num + randomAddCount
  474. UserDefaults.standard.setValue(num, forKey: QSLConfig.user_default_local_buy_count)
  475. self.peopleCountLabel.text("\(num)人 已开通VIP")
  476. }
  477. }
  478. // MARK: - 设置 CollectionView
  479. extension QSLVipController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  480. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  481. return goodList.count
  482. }
  483. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  484. let cell = collectionView.dequeueReusableCell(cellType: QSLVipGoodCollectionViewCell.self, cellForRowAt: indexPath)
  485. let model = self.goodList[indexPath.row]
  486. cell.config(model: model)
  487. return cell
  488. }
  489. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  490. for i in 0..<self.goodList.count {
  491. self.goodList[i].isSelect = false
  492. }
  493. self.goodList[indexPath.row].isSelect = true
  494. self.selectGood = self.goodList[indexPath.row]
  495. switch self.selectGood?.level {
  496. case 100 :
  497. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  498. break
  499. case 700:
  500. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  501. break;
  502. case 3100:
  503. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  504. break;
  505. case 9200:
  506. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  507. break;
  508. case 36600:
  509. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  510. break;
  511. case 3660000:
  512. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  513. break;
  514. default:
  515. break;
  516. }
  517. self.goodsCollectionView.reloadData()
  518. }
  519. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  520. return CGSize(width: 104.rpx, height: 143.rpx)
  521. }
  522. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  523. return 4.rpx
  524. }
  525. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  526. return 0
  527. }
  528. }
  529. extension QSLVipController {
  530. func updateUI() {
  531. if QSLBaseManager.shared.isLogin() && QSLBaseManager.shared.isVip() {
  532. let model = QSLBaseManager.shared.userModel.memberModel
  533. if model.permanent {
  534. self.vipTimeLabel.text("您已是尊贵的永久会员")
  535. self.bottomView.isHidden = true
  536. } else {
  537. let level = model.memberLevelString()
  538. let endTime = model.endTimestampString()
  539. self.vipTimeLabel.text("\(level):\(endTime)到期")
  540. }
  541. } else {
  542. self.vipTimeLabel.text("升级VIP会员,解锁全部功能")
  543. }
  544. }
  545. func updateSelectGoodUI() {
  546. var priceText = ""
  547. var originalPriceText = ""
  548. if let selectGood = self.selectGood {
  549. if selectGood.amount.truncatingRemainder(dividingBy: 100) == 0 {
  550. priceText = "\(Int(selectGood.amount / 100))"
  551. } else {
  552. priceText = String(format: "%.2lf", selectGood.amount / 100 )
  553. }
  554. if selectGood.originalAmount.truncatingRemainder(dividingBy: 100) == 0 {
  555. originalPriceText = "\(Int(selectGood.originalAmount / 100))"
  556. } else {
  557. originalPriceText = String(format: "%.2lf", selectGood.originalAmount / 100 )
  558. }
  559. }
  560. self.priceLabel.text(priceText)
  561. // self.goodTypeLabel.text("/ \(self.selectGood?.name ?? "")")
  562. self.goodOriginalPriceLabel.text("原价\(originalPriceText)")
  563. }
  564. func initializeView() {
  565. self.view.addSubview(vipBg)
  566. vipBg.snp.makeConstraints { make in
  567. make.left.top.right.equalTo(0)
  568. }
  569. self.view.addSubview(backButton)
  570. backButton.snp.makeConstraints { make in
  571. make.size.equalTo(100.rpx)
  572. make.height.equalTo(25.rpx)
  573. make.left.equalTo(12.rpx)
  574. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  575. }
  576. self.view.addSubview(peopleCountView)
  577. peopleCountView.snp.makeConstraints { make in
  578. make.size.equalTo(CGSize(width: 212.rpx, height: 24.rpx))
  579. make.right.equalTo(-13.rpx)
  580. make.centerY.equalTo(backButton.snp.centerY)
  581. }
  582. peopleCountView.addSubview(peopleAvatarImageView)
  583. peopleAvatarImageView.snp.makeConstraints { make in
  584. make.size.equalTo(CGSize(width: 72.rpx, height: 16.6.rpx))
  585. make.left.equalTo(3.rpx)
  586. make.centerY.equalTo(peopleCountView.snp.centerY)
  587. }
  588. peopleCountView.addSubview(peopleCountLabel)
  589. peopleCountLabel.snp.makeConstraints { make in
  590. make.left.equalTo(peopleAvatarImageView.snp.right).offset(7.rpx)
  591. make.centerY.equalTo(peopleCountView.snp.centerY)
  592. }
  593. self.view.addSubview(scrollView)
  594. scrollView.snp.makeConstraints { make in
  595. make.left.right.equalTo(0)
  596. make.top.equalTo(QSLConst.qsl_kNavFrameH)
  597. make.bottom.equalTo(0)
  598. }
  599. scrollView.addSubview(cardBannerImageView)
  600. cardBannerImageView.snp.makeConstraints { make in
  601. make.top.equalTo(0)
  602. make.centerX.equalToSuperview()
  603. make.width.equalTo(336.rpx)
  604. make.height.equalTo(108.rpx)
  605. }
  606. cardBannerImageView.addSubview(vipTimeLabel)
  607. vipTimeLabel.snp.makeConstraints { make in
  608. make.left.equalTo(23.rpx)
  609. make.bottom.equalTo(-19.rpx)
  610. }
  611. scrollView.addSubview(funcBannerImageView)
  612. funcBannerImageView.snp.makeConstraints { make in
  613. make.size.equalTo(CGSize(width: 336.rpx, height: 172.rpx))
  614. make.centerX.equalToSuperview()
  615. make.top.equalTo(cardBannerImageView.snp.bottom).offset(14.rpx)
  616. }
  617. scrollView.addSubview(mainView)
  618. mainView.snp.makeConstraints { make in
  619. make.left.right.bottom.equalTo(0)
  620. make.top.equalTo(funcBannerImageView.snp.bottom).offset(-24.rpx)
  621. make.width.equalTo(QSLConst.qsl_kScreenW)
  622. make.height.equalTo(800.rpx)
  623. }
  624. mainView.addSubview(goodsBgView)
  625. goodsBgView.snp.makeConstraints { make in
  626. make.top.left.right.equalTo(0)
  627. make.width.equalTo(QSLConst.qsl_kScreenW)
  628. make.height.equalTo(255.rpx)
  629. }
  630. goodsBgView.addSubview(vipGoodsTitleIcon)
  631. vipGoodsTitleIcon.snp.makeConstraints { make in
  632. make.size.equalTo(CGSize(width: 117.rpx, height: 26.rpx))
  633. make.left.equalTo(20.rpx)
  634. make.top.equalTo(16.rpx)
  635. }
  636. goodsBgView.addSubview(resumeBtn)
  637. resumeBtn.snp.makeConstraints { make in
  638. make.size.equalTo(CGSize(width: 75.rpx, height: 16.rpx))
  639. make.right.equalTo(-18.rpx)
  640. make.centerY.equalTo(vipGoodsTitleIcon.snp.centerY)
  641. }
  642. goodsBgView.addSubview(goodsCollectionView)
  643. goodsCollectionView.snp.makeConstraints { make in
  644. make.left.equalTo(18.rpx)
  645. make.right.equalTo(-22.rpx)
  646. make.height.equalTo(143.rpx)
  647. make.top.equalTo(vipGoodsTitleIcon.snp.bottom).offset(10.rpx)
  648. }
  649. goodsBgView.addSubview(selectBtn)
  650. selectBtn.snp.makeConstraints { make in
  651. make.size.equalTo(CGSize(width: 12.rpx, height: 12.rpx))
  652. make.left.equalTo(23.rpx)
  653. make.top.equalTo(goodsCollectionView.snp.bottom).offset(16.rpx)
  654. }
  655. goodsBgView.addSubview(serviceLabel)
  656. serviceLabel.snp.makeConstraints { make in
  657. make.left.equalTo(selectBtn.snp.right).offset(2.rpx)
  658. make.centerY.equalTo(selectBtn.snp.centerY)
  659. }
  660. mainView.addSubview(commentView)
  661. commentView.snp.makeConstraints { make in
  662. make.left.right.equalTo(0)
  663. make.top.equalTo(goodsBgView.snp.bottom).offset(8.rpx)
  664. make.bottom.equalTo(0)
  665. }
  666. commentView.addSubview(commentTitleIcon)
  667. commentTitleIcon.snp.makeConstraints { make in
  668. make.size.equalTo(CGSize(width: 83.rpx, height: 26.rpx))
  669. make.top.equalTo(16.rpx)
  670. make.left.equalTo(12.rpx)
  671. }
  672. let commentHeight1 = "上班没时间,远程遛娃,非常方便很好用。".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  673. commentView.addSubview(comment1)
  674. comment1.snp.makeConstraints { make in
  675. make.left.right.equalTo(0)
  676. make.top.equalTo(commentTitleIcon.snp.bottom).offset(16.rpx)
  677. make.height.equalTo(commentHeight1)
  678. }
  679. let commentHeight2 = "用了之后,才发现真的可以找到他。".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  680. commentView.addSubview(comment2)
  681. comment2.snp.makeConstraints { make in
  682. make.left.right.equalTo(0)
  683. make.top.equalTo(comment1.snp.bottom).offset(30.rpx)
  684. make.height.equalTo(commentHeight2)
  685. }
  686. let commentHeight3 = "轨迹很准,一目了然,奶奶出门遇到危险直接一键报警,我就收到信息了".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  687. commentView.addSubview(comment3)
  688. comment3.snp.makeConstraints { make in
  689. make.left.right.equalTo(0)
  690. make.top.equalTo(comment2.snp.bottom).offset(30.rpx)
  691. make.height.equalTo(commentHeight3)
  692. }
  693. commentView.addSubview(tipTitleLabel)
  694. commentView.addSubview(tipContentLabel)
  695. tipTitleLabel.snp.makeConstraints { make in
  696. make.left.equalTo(16)
  697. make.top.equalTo(comment3.snp.bottom).offset(28)
  698. }
  699. tipContentLabel.snp.makeConstraints { make in
  700. make.left.equalTo(16)
  701. make.right.equalTo(-16)
  702. make.top.equalTo(tipTitleLabel.snp.bottom).offset(11)
  703. }
  704. scrollView.snp.makeConstraints { make in
  705. make.bottom.equalTo(mainView)
  706. }
  707. self.view.addSubview(bottomView)
  708. bottomView.snp.makeConstraints { make in
  709. make.left.equalTo(12.rpx)
  710. make.right.equalTo(-12.rpx)
  711. make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom)
  712. make.height.equalTo(50.rpx)
  713. }
  714. bottomView.addSubview(unlockBtn)
  715. unlockBtn.snp.makeConstraints { make in
  716. make.right.top.bottom.equalTo(0)
  717. make.width.equalTo(165.rpx)
  718. }
  719. bottomView.addSubview(priceIconLabel)
  720. priceIconLabel.snp.makeConstraints { make in
  721. make.left.equalTo(20.rpx)
  722. make.bottom.equalTo(-12.rpx)
  723. }
  724. bottomView.addSubview(priceLabel)
  725. priceLabel.snp.makeConstraints { make in
  726. make.left.equalTo(priceIconLabel.snp.right).offset(2.rpx)
  727. make.bottom.equalTo(-10.rpx)
  728. }
  729. bottomView.addSubview(goodTypeLabel)
  730. goodTypeLabel.snp.makeConstraints { make in
  731. make.left.equalTo(priceLabel.snp.right).offset(2.rpx)
  732. make.bottom.equalTo(-14.rpx)
  733. }
  734. bottomView.addSubview(goodOriginalPriceLabel)
  735. goodOriginalPriceLabel.snp.makeConstraints { make in
  736. make.left.equalTo(goodTypeLabel.snp.right).offset(2.rpx)
  737. make.centerY.equalTo(goodTypeLabel.snp.centerY)
  738. }
  739. }
  740. }