QSLVipController.swift 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  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. case guideComments // 引导评论
  16. }
  17. class QSLVipController: QSLBaseController {
  18. // 购买人数
  19. static let record_non_member_clicks_to_claim = "RECORD_NON_MEMBER_CLIKS_CLAIM"
  20. struct UX {
  21. static let mostCellHeight = 113.0.rpx
  22. static let collectionRowHeight = 137.0.rpx
  23. static let goodsBgHeight = 54.rpx + UX.mostCellHeight + 20.rpx
  24. }
  25. var type: QSLVipJumpType?
  26. var isCancel = false
  27. var yearGood : QSLGoodModel?
  28. var finishHandler: ((Bool,QSLGoodModel?) -> Void)?
  29. var goodList: [QSLGoodModel] = [QSLGoodModel]()
  30. ///是否是订阅的产品
  31. //var is
  32. var selectGood: QSLGoodModel? {
  33. didSet {
  34. updateSelectGoodUI()
  35. }
  36. }
  37. lazy var vipBg: UIImageView = {
  38. let imageView = UIImageView()
  39. imageView.image = UIImage(named: "vip_bg")
  40. return imageView
  41. }()
  42. lazy var backButton: UIButton = {
  43. let button = UIButton()
  44. button.image(UIImage(named: "public_back_btn_white"))
  45. button.title("会员中心")
  46. button.mediumFont(17)
  47. button.textColor(.white)
  48. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  49. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  50. return button
  51. }()
  52. lazy var peopleCountView: UIView = {
  53. let view = UIView()
  54. view.layer.cornerRadius = 12.rpx
  55. view.layer.borderColor = UIColor.white.withAlphaComponent(0.16).cgColor
  56. view.layer.borderWidth = 1.rpx
  57. return view
  58. }()
  59. lazy var peopleAvatarImageView: UIImageView = {
  60. let imageView = UIImageView()
  61. imageView.image = UIImage(named: "vip_avatars_icon")
  62. return imageView
  63. }()
  64. lazy var peopleCountLabel: UILabel = {
  65. let label = UILabel()
  66. label.text("1456488人 已开通VIP")
  67. label.color("#FFE6C0")
  68. label.font(12)
  69. return label
  70. }()
  71. lazy var scrollView: UIScrollView = {
  72. let scrollView = UIScrollView()
  73. // scrollView.delegate = self
  74. scrollView.bounces = false
  75. scrollView.showsVerticalScrollIndicator = false
  76. scrollView.contentInsetAdjustmentBehavior = .never
  77. return scrollView
  78. }()
  79. lazy var cardBannerImageView: UIImageView = {
  80. let imageView = UIImageView()
  81. imageView.image = UIImage(named: "vip_banner_card")
  82. return imageView
  83. }()
  84. lazy var vipTimeLabel: UILabel = {
  85. let label = UILabel()
  86. label.text("升级VIP会员,解锁全部功能")
  87. label.font(13)
  88. label.textColor = .hexStringColor(hexString: "#AF7655")
  89. return label
  90. }()
  91. lazy var funcBannerImageView: UIImageView = {
  92. let imageView = UIImageView()
  93. imageView.image = UIImage(named: "vip_banner_func")
  94. return imageView
  95. }()
  96. lazy var mainView: UIView = {
  97. let view = UIView()
  98. view.backgroundColor = QSLColor.backGroundColor
  99. view.addRadius(radius: 12.rpx)
  100. return view
  101. }()
  102. lazy var goodsBgView: UIView = {
  103. let view = UIView()
  104. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FFF8F2"), color2: .hexStringColor(hexString: "#FFFFFF"), width: QSLConst.qsl_kScreenW, height: UX.goodsBgHeight, direction: .vertical)
  105. return view
  106. }()
  107. lazy var vipGoodsTitleIcon: UIImageView = {
  108. let imageView = UIImageView()
  109. imageView.image = UIImage(named: "vip_title_icon")
  110. return imageView
  111. }()
  112. lazy var resumeBtn: UIButton = {
  113. let button = UIButton()
  114. button.title("恢复购买")
  115. button.setTitleColor(.hexStringColor(hexString: "#000000").withAlphaComponent(0.5), for: .normal)
  116. button.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: .medium)
  117. button.image(UIImage(named: "vip_resume_btn"))
  118. button.setImageTitleLayout(.imgLeft, spacing: 2.rpx)
  119. button.addTarget(self, action: #selector(resumeBtnAction), for: .touchUpInside)
  120. return button
  121. }()
  122. lazy var mostCell: QSLVipMostGoodCell = {
  123. let cell = QSLVipMostGoodCell()
  124. cell.isUserInteractionEnabled = true
  125. let tap = UITapGestureRecognizer(target: self, action: #selector(firstCellClickAction))
  126. cell.addGestureRecognizer(tap)
  127. return cell
  128. }()
  129. lazy var goodsCollectionView: UICollectionView = {
  130. let layout = UICollectionViewFlowLayout()
  131. layout.minimumLineSpacing = 0
  132. layout.scrollDirection = .vertical
  133. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  134. collectionView.backgroundColor = .clear
  135. collectionView.dataSource = self
  136. collectionView.delegate = self
  137. collectionView.showsHorizontalScrollIndicator = false
  138. collectionView.bounces = false
  139. collectionView.register(cellClass: QSLVipGoodCollectionViewCell.self)
  140. return collectionView
  141. }()
  142. lazy var selectBtn: UIButton = {
  143. let btn = UIButton()
  144. btn.image(UIImage(named: "public_select_btn_false"), .normal)
  145. btn.image(UIImage(named: "public_select_btn_true"), .selected)
  146. btn.addTarget(self, action: #selector(selectBtnAction), for: .touchUpInside)
  147. return btn
  148. }()
  149. lazy var serviceLabel: YYLabel = {
  150. let label = YYLabel()
  151. //updateServiceLabelText(showSubscribe: true) // 默认显示所有内容
  152. return label
  153. }()
  154. // 更新服务条款文本内容
  155. func updateServiceLabelText(showSubscribe: Bool) {
  156. let attr = NSMutableAttributedString()
  157. // 固定部分:购买即同意
  158. let firstAttr = NSMutableAttributedString(string: "购买即同意")
  159. firstAttr.font(10)
  160. firstAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  161. attr.append(firstAttr)
  162. let blankAttr = NSMutableAttributedString(string: " ")
  163. blankAttr.font(10)
  164. attr.append(blankAttr)
  165. // 《隐私权政策》
  166. let privacyHL = YYTextHighlight()
  167. let privacyStr = "《隐私权政策》"
  168. let privacyText = NSMutableAttributedString(string: privacyStr)
  169. privacyText.font(10)
  170. privacyText.color(.hexStringColor(hexString: "#E7B983"))
  171. privacyText.yy_setTextHighlight(privacyHL, range: NSRange(location: 0, length: privacyStr.count))
  172. privacyHL.tapAction = { [weak self] containerView, text, range, rect in
  173. self?.privacyAction()
  174. }
  175. attr.append(privacyText)
  176. attr.append(blankAttr)
  177. // 《用户协议》
  178. let serviceHL = YYTextHighlight()
  179. let serviceStr = "《用户协议》"
  180. let serviceText = NSMutableAttributedString(string: serviceStr)
  181. serviceText.font(10)
  182. serviceText.color(.hexStringColor(hexString: "#E7B983"))
  183. serviceText.yy_setTextHighlight(serviceHL, range: NSRange(location: 0, length: serviceStr.count))
  184. serviceHL.tapAction = { [weak self] containerView, text, range, rect in
  185. self?.serviceAction()
  186. }
  187. attr.append(serviceText)
  188. // 根据条件决定是否添加《续订说明》相关内容
  189. if showSubscribe {
  190. attr.append(blankAttr)
  191. let andAttr = NSMutableAttributedString(string: "和")
  192. andAttr.font(10)
  193. andAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  194. attr.append(andAttr)
  195. attr.append(blankAttr)
  196. let subcribeHL = YYTextHighlight()
  197. let subcribeStr = "《续订说明》"
  198. let subcribeText = NSMutableAttributedString(string: subcribeStr)
  199. subcribeText.font(10)
  200. subcribeText.color(.hexStringColor(hexString: "#E7B983"))
  201. subcribeText.yy_setTextHighlight(subcribeHL, range: NSRange(location: 0, length: subcribeStr.count))
  202. subcribeHL.tapAction = { [weak self] containerView, text, range, rect in
  203. self?.subscibeAction()
  204. }
  205. attr.append(subcribeText)
  206. }
  207. serviceLabel.attributedText = attr
  208. }
  209. // 在需要隐藏《续订说明》时调用此方法
  210. func hideSubscribeDescription() {
  211. updateServiceLabelText(showSubscribe: false)
  212. }
  213. // 在需要显示《续订说明》时调用此方法
  214. func showSubscribeDescription() {
  215. updateServiceLabelText(showSubscribe: true)
  216. }
  217. lazy var commentView: UIView = {
  218. let view = UIView()
  219. view.backgroundColor = .white
  220. return view
  221. }()
  222. lazy var commentTitleIcon: UIImageView = {
  223. let imageView = UIImageView()
  224. imageView.image = UIImage(named: "vip_comment_title_icon")
  225. return imageView
  226. }()
  227. lazy var comment1: QSLVipCommentCellView = {
  228. let view = QSLVipCommentCellView()
  229. view.config(name: "用户189****7913", comment: "上班没时间,远程遛娃,非常方便很好用。")
  230. return view
  231. }()
  232. lazy var comment2: QSLVipCommentCellView = {
  233. let view = QSLVipCommentCellView()
  234. view.config(name: "用户189****7913", comment: "用了之后,才发现真的可以找到他。")
  235. return view
  236. }()
  237. lazy var comment3: QSLVipCommentCellView = {
  238. let view = QSLVipCommentCellView()
  239. view.config(name: "用户189****7913", comment: "轨迹很准,一目了然,奶奶出门遇到危险直接一键报警,我就收到信息了")
  240. return view
  241. }()
  242. lazy var tipTitleLabel: UILabel = {
  243. let label = UILabel()
  244. label.text("温馨提示")
  245. label.font(12)
  246. label.textColor = .hexStringColor(hexString: "#000000").withAlphaComponent(0.8)
  247. return label
  248. }()
  249. lazy var tipContentLabel: UILabel = {
  250. let label = UILabel()
  251. label.numberOfLines = 0
  252. label.text("1 订阅后会从您的iTunes账户中扣除相关费用。如需取消续订,请在当前订阅周期结束前,至少24小时内通过手机“账户设置”的订阅管理关闭自动续费功能。\n2 未成年人请在监护者的陪同下进行购买\n3 购买后不支持退款,请仔细审阅《隐私权政策》《用户协议》和《续订说明》")
  253. label.font(10)
  254. label.textColor = .hexStringColor(hexString: "#000000").withAlphaComponent(0.6)
  255. label.changeLineSpace(space: 5)
  256. return label
  257. }()
  258. lazy var bottomContentView: UIView = {
  259. let view = UIView()
  260. return view
  261. }()
  262. lazy var bottomTopView: UIView = {
  263. let view = UIView()
  264. view.isHidden = true
  265. view.backgroundColor = .hexStringColor(hexString: "#FFFED8")
  266. view.addRadius(radius: 30.rpx)
  267. return view
  268. }()
  269. lazy var bottomTopLabel: UILabel = {
  270. let label = UILabel()
  271. label.text = ""
  272. return label
  273. }()
  274. func bottomTopLabelInfo(_ goodInfo : QSLGoodModel) {
  275. let darkGrayAttributes: [NSAttributedString.Key: Any] = [
  276. .foregroundColor: UIColor.hexStringColor(hexString: "#404040"),
  277. .font: UIFont.systemFont(ofSize: 11),
  278. .paragraphStyle: {
  279. let paragraphStyle = NSMutableParagraphStyle()
  280. paragraphStyle.alignment = .center
  281. return paragraphStyle
  282. }(),
  283. .kern: -1
  284. ]
  285. // 创建绿色文本样式
  286. let greenAttributes: [NSAttributedString.Key: Any] = [
  287. .foregroundColor: UIColor.hexStringColor(hexString: "#EE6C1C"),
  288. .font: UIFont.systemFont(ofSize: 15, weight: .black),
  289. .paragraphStyle: {
  290. let paragraphStyle = NSMutableParagraphStyle()
  291. paragraphStyle.alignment = .center
  292. return paragraphStyle
  293. }(),
  294. .kern: -1
  295. ]
  296. let textArray = goodInfo.text.components(separatedBy: goodInfo.keys.key)
  297. if textArray.count > 0 && goodInfo.text.count > 0{
  298. bottomTopView.isHidden = false
  299. let inputtr = NSMutableAttributedString()
  300. let titleOneAttr = NSAttributedString(string: textArray.first ?? "", attributes: darkGrayAttributes)
  301. let titleTwoAttr = NSAttributedString(string: " \(goodInfo.keys.value) ", attributes: greenAttributes)
  302. inputtr.append(titleOneAttr)
  303. inputtr.append(titleTwoAttr)
  304. if textArray.count > 1 {
  305. let titleThreeAttr = NSAttributedString(string: textArray[1], attributes: darkGrayAttributes)
  306. inputtr.append(titleThreeAttr)
  307. }
  308. bottomTopLabel.attributedText = inputtr
  309. } else {
  310. bottomTopView.isHidden = true
  311. }
  312. }
  313. lazy var bottomView: UIView = {
  314. let view = UIView()
  315. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#00434E"), color2: .hexStringColor(hexString: "#0E5E61"), width: QSLConst.qsl_kScreenW - 24.rpx, height: 50.rpx, direction: .horizontal)
  316. view.addRadius(radius: 25.rpx)
  317. return view
  318. }()
  319. lazy var unlockBtn: UIButton = {
  320. let btn = UIButton()
  321. btn.setBackgroundImage(UIImage(named: "vip_unlock_btn_bg"), for: .normal)
  322. btn.title("立即解锁")
  323. btn.textColor(.hexStringColor(hexString: "#9B3800"))
  324. btn.mediumFont(18)
  325. btn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 30.rpx, bottom: 0, right: 0)
  326. btn.addTarget(self, action: #selector(unlockBtnAction), for: .touchUpInside)
  327. return btn
  328. }()
  329. lazy var priceIconLabel: UILabel = {
  330. let label = UILabel()
  331. label.text("¥")
  332. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  333. label.font(14)
  334. return label
  335. }()
  336. lazy var priceLabel: UILabel = {
  337. let label = UILabel()
  338. label.text("168")
  339. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  340. label.font(24)
  341. return label
  342. }()
  343. lazy var goodTypeLabel: UILabel = {
  344. let label = UILabel()
  345. label.text("/")
  346. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  347. label.font(12)
  348. return label
  349. }()
  350. lazy var goodOriginalPriceLabel: UILabel = {
  351. let label = UILabel()
  352. label.text("原价228")
  353. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  354. label.font(12)
  355. label.centerLineText(lineValue: 1, underlineColor: .hexStringColor(hexString: "#FFF8EF"))
  356. return label
  357. }()
  358. deinit {
  359. self.finishHandler?(self.isCancel,self.yearGood)
  360. }
  361. override func viewDidLoad() {
  362. super.viewDidLoad()
  363. initializeView()
  364. updateUI()
  365. requestItemList()
  366. calculateBuyCount()
  367. // if(QSLBaseManager.shared.isLogin()){
  368. // self.resumeBtn.isHidden = false
  369. // }else{
  370. // self.resumeBtn.isHidden = true
  371. // }
  372. if let type = self.type {
  373. switch type {
  374. case .homeRoad:
  375. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1001])
  376. gravityInstance?.track(QSLGravityConst.new_vip_show, properties: ["is_member":QSLBaseManager.shared.isVip(),"entry_point":"track"])
  377. case .add:
  378. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1002])
  379. gravityInstance?.track(QSLGravityConst.new_vip_show, properties: ["is_member":QSLBaseManager.shared.isVip(),"entry_point":"find_friend"])
  380. case .friendRoad:
  381. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1003])
  382. gravityInstance?.track(QSLGravityConst.new_vip_show, properties: ["is_member":QSLBaseManager.shared.isVip(),"entry_point":"find_track"])
  383. case .contact:
  384. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1004])
  385. gravityInstance?.track(QSLGravityConst.new_vip_show, properties: ["is_member":QSLBaseManager.shared.isVip(),"entry_point":"contact"])
  386. case .mine:
  387. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1006])
  388. gravityInstance?.track(QSLGravityConst.new_vip_show, properties: ["is_member":QSLBaseManager.shared.isVip(),"entry_point":"open_now"])
  389. case .guideComments:
  390. print("")
  391. }
  392. }
  393. }
  394. }
  395. extension QSLVipController {
  396. @objc func privacyAction() {
  397. let vc = QSLWebViewController()
  398. vc.webUrl = QSLConfig.AppPrivacyAgreementLink
  399. vc.title = "隐私政策"
  400. self.navigationController?.pushViewController(vc, animated: true)
  401. }
  402. @objc func serviceAction() {
  403. let vc = QSLWebViewController()
  404. vc.webUrl = QSLConfig.AppServiceAgreementLink
  405. vc.title = "服务协议"
  406. self.navigationController?.pushViewController(vc, animated: true)
  407. }
  408. @objc func subscibeAction() {
  409. let vc = QSLWebViewController()
  410. vc.webUrl = QSLConfig.AppSubscibeAgreementLink
  411. vc.title = "续订说明"
  412. self.navigationController?.pushViewController(vc, animated: true)
  413. }
  414. @objc func selectBtnAction() {
  415. selectBtn.isSelected = !selectBtn.isSelected
  416. }
  417. // 恢复按钮点击
  418. @objc func resumeBtnAction() {
  419. let memberModel = QSLBaseManager.shared.userModel.memberModel
  420. let expired = memberModel.expired
  421. if !expired {
  422. QSLLoading.success(text: "您已经在订阅中,无需恢复")
  423. return
  424. }
  425. QSLLoading.show()
  426. QSLVipManager.shared.restoreAction { isSuccess in
  427. QSLVipManager.shared.isPaying = false
  428. if isSuccess {
  429. QSLNetwork().request(.userMember(dict: [:])) { response in
  430. let model = response.mapObject(QSLMemberModel.self, modelKey: "data")
  431. QSLBaseManager.shared.userModel.memberModel = model
  432. if model.expired {
  433. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  434. } else {
  435. QSLBaseManager.shared.saveVipExpiredTime(time: model.endTimestamp)
  436. }
  437. QSLBaseManager.shared.saveUserId(id: model.userId)
  438. if model.endTimestamp > memberModel.endTimestamp {
  439. QSLLoading.success(text: "恢复成功")
  440. // 支付成功通知
  441. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  442. self.navigationController?.popViewController(animated: true)
  443. }
  444. } else {
  445. QSLLoading.error(text: "没有可供恢复的订阅")
  446. }
  447. } fail: { code, error in
  448. QSLLoading.error(text: "没有可供恢复的订阅")
  449. }
  450. } else {
  451. QSLLoading.error(text: "没有可供恢复的订阅")
  452. }
  453. }
  454. }
  455. // 支付按钮点击
  456. @objc func unlockBtnAction() {
  457. if let curGood = self.selectGood {
  458. QSLCountdownManager.shared.selectGood = curGood
  459. }
  460. switch self.selectGood?.level {
  461. case 100 :
  462. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1006])
  463. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "day"])
  464. break
  465. case 700:
  466. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1005])
  467. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "weekly"])
  468. break;
  469. case 3100:
  470. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1004])
  471. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "monthly"])
  472. break;
  473. case 9200:
  474. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1003])
  475. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "quarterly"])
  476. break;
  477. case 36600:
  478. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1002])
  479. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "yearly"])
  480. break;
  481. case 3660000:
  482. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1001])
  483. gravityInstance?.track(QSLGravityConst.new_vip_click, properties: ["is_member":QSLBaseManager.shared.isVip(),"package_type": "lifetime"])
  484. break;
  485. default:
  486. break;
  487. }
  488. // if !selectBtn.isSelected {
  489. // self.view.toast(text: "请先同意《隐私权政策》和《用户协议》")
  490. // return
  491. // }
  492. let memberModel = QSLBaseManager.shared.userModel.memberModel
  493. if let subscriptionExpired = memberModel.subscriptionExpired, !subscriptionExpired {
  494. self.view.toast(text: "你已经订阅了")
  495. return
  496. }
  497. if goodList.count > 0, let selectGood = self.selectGood {
  498. QSLLoading.showWithCancel()
  499. QSLVipManager.shared.startPay(goods: selectGood) { [self] status, outTradeNo in
  500. QSLVipManager.shared.isPaying = false
  501. if status == .success {
  502. QSLLoading.success(text: "支付成功")
  503. self.isCancel = true
  504. gravityInstance?.track(QSLGravityConst.new_vip_result, properties: ["is_member":QSLBaseManager.shared.isVip(),"purchase_result": "success","pay_amount":Int32(selectGood.amount)])
  505. //支付成功埋点
  506. gravityInstance?.track(QSLGravityConst.vip_submit_success, properties: ["id": 01001])
  507. //弹出是否好评的弹窗
  508. // QSLGuideusersToCommentManager.commentShare.manageWhetherTriggerPopUpWindow(QSLGuideusersToCommentType.member)
  509. // 引力传递支付事件
  510. if let selectGood = self.selectGood {
  511. gravityInstance?.trackPayEvent(withAmount: Int32(selectGood.amount), withPayType: "CNY", withOrderId: outTradeNo, withPayReason: selectGood.name, withPayMethod: "apple")
  512. }
  513. #if DEBUG
  514. #else
  515. //苹果广告奇异果传递支付事件
  516. QSWikiHandle.shared.addEventResultAttribution(eventDict: ["event_name": "pay", "event_val": selectGood.amount])
  517. #endif
  518. if let type = self.type {
  519. switch type {
  520. case .homeRoad:
  521. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1001])
  522. case .add:
  523. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1002])
  524. case .friendRoad:
  525. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1003])
  526. case .contact:
  527. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1004])
  528. case .mine:
  529. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1006])
  530. case .guideComments:
  531. print("")
  532. }
  533. }
  534. switch self.selectGood?.level {
  535. case 100 :
  536. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 1])
  537. break
  538. case 700:
  539. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 5])
  540. break;
  541. case 3100:
  542. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 9])
  543. break;
  544. case 9200:
  545. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 13])
  546. break;
  547. case 36600:
  548. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 17])
  549. break;
  550. case 3660000:
  551. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 21])
  552. break;
  553. default:
  554. break;
  555. }
  556. DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
  557. self.navigationController?.popViewController(animated: true)
  558. NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  559. if(!QSLBaseManager.shared.isLogin()){
  560. QSLJumpManager.shared.pushToLogin(type: .member)
  561. }
  562. }
  563. } else if status == .cancel {
  564. gravityInstance?.track(QSLGravityConst.new_vip_result, properties: ["is_member":QSLBaseManager.shared.isVip(),"purchase_result": "cancel","pay_amount":Int32(selectGood.amount)])
  565. QSLLoading.error(text: "支付取消")
  566. payFailAlertTip()
  567. gravityInstance?.track(QSLGravityConst.new_vip_retention_show, properties: ["trigger_type":"cancel_payment"])
  568. } else if status == .fail {
  569. gravityInstance?.track(QSLGravityConst.new_vip_result, properties: ["is_member":QSLBaseManager.shared.isVip(),"purchase_result": "fail","pay_amount":Int32(selectGood.amount)])
  570. gravityInstance?.track(QSLGravityConst.vip_fail)
  571. QSLLoading.error(text: "支付失败")
  572. payFailAlertTip()
  573. gravityInstance?.track(QSLGravityConst.new_vip_retention_show, properties: ["trigger_type":"fail"])
  574. }
  575. }
  576. }
  577. }
  578. func payFailAlertTip() {
  579. if let currentWindow = UIApplication.keyWindow {
  580. self.isCancel = true
  581. QSLRetainPopUpAlertView.alert(view: currentWindow, isOneBtn: true, oneBtnText: "继续支付", oneBtnClosure: { [weak self] in
  582. self?.unlockBtnAction()
  583. gravityInstance?.track(QSLGravityConst.new_vip_retention_click, properties: ["button":"continue_payment"])
  584. },closeBtnClosure: {
  585. gravityInstance?.track(QSLGravityConst.new_vip_retention_click, properties: ["button":"close"])
  586. })
  587. }
  588. }
  589. @objc func firstCellClickAction() {
  590. for i in 0..<self.goodList.count {
  591. self.goodList[i].isSelect = false
  592. }
  593. if self.goodList.count > 0 {
  594. self.goodList[0].isSelect = true
  595. self.selectGood = self.goodList[0]
  596. self.mostCell.config(model: self.goodList[0])
  597. //选中立即支付
  598. unlockBtnAction()
  599. }
  600. switch self.selectGood?.level {
  601. case 100 :
  602. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  603. break
  604. case 700:
  605. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  606. break;
  607. case 3100:
  608. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  609. break;
  610. case 9200:
  611. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  612. break;
  613. case 36600:
  614. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  615. break;
  616. case 3660000:
  617. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  618. break;
  619. default:
  620. break;
  621. }
  622. self.goodsCollectionView.reloadData()
  623. }
  624. }
  625. extension QSLVipController {
  626. // 请求商品列表
  627. func requestItemList() {
  628. // 定义并赋值 itemListDict(根据条件变化)
  629. var itemListDict: [String: Any] = ["itemListType": 2]
  630. if UserDefaults.standard.string(forKey: QSLVipController.record_non_member_clicks_to_claim) == nil && self.type == .guideComments {
  631. itemListDict = ["itemListType": 2, "showExtraText": true]
  632. // 记录非会员点击领取
  633. UserDefaults.standard.set("YES", forKey: QSLVipController.record_non_member_clicks_to_claim)
  634. UserDefaults.standard.synchronize()
  635. }
  636. // 网络请求时使用 itemListDict 作为参数(关键修复)
  637. QSLNetwork().request(.vipItemList(dict: itemListDict)) { response in
  638. // 后续逻辑不变...
  639. let list = response.mapArray(QSLGoodModel.self, modelKey: "data>list")
  640. self.goodList = list
  641. if self.goodList.count > 0 {
  642. self.goodList[0].isSelect = true
  643. self.selectGood = self.goodList[0]
  644. QSLCountdownManager.shared.selectGood = self.goodList[0]
  645. self.mostCell.config(model: self.goodList[0])
  646. let row = ceil(Double(self.goodList.count - 1) / 3.0)
  647. let height = UX.goodsBgHeight + (row * UX.collectionRowHeight)
  648. self.goodsBgView.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FFF8F2"), color2: .hexStringColor(hexString: "#FFFFFF"), width: QSLConst.qsl_kScreenW, height: height, direction: .vertical)
  649. self.goodsBgView.snp.updateConstraints { make in
  650. make.height.equalTo(height)
  651. }
  652. self.scrollView.snp.makeConstraints { make in
  653. make.bottom.equalTo(self.mainView)
  654. }
  655. self.checkRenewalOfProducts()
  656. var yearGood = self.selectGood
  657. for subGood in self.goodList{
  658. if(subGood.level == 36600){
  659. yearGood = subGood
  660. break
  661. }
  662. }
  663. self.yearGood = yearGood
  664. }
  665. self.goodsCollectionView.reloadData()
  666. } fail: { code, error in
  667. self.view.toast(text: "加载商品列表失败")
  668. }
  669. }
  670. ///检查有没有续订的产品
  671. func checkRenewalOfProducts() {
  672. let hasSubscribable = self.goodList.contains(where: { model in
  673. return model.subscribable == 1
  674. })
  675. if hasSubscribable == false {
  676. tipContentLabel.isHidden = true
  677. hideSubscribeDescription()
  678. serviceLabel.snp.removeConstraints()
  679. serviceLabel.snp.makeConstraints { make in
  680. make.left.equalTo(16)
  681. make.top.equalTo(comment3.snp.bottom).offset(28.rpx)
  682. }
  683. } else {
  684. tipContentLabel.isHidden = false
  685. showSubscribeDescription()
  686. }
  687. }
  688. // 计算购买人数
  689. func calculateBuyCount() {
  690. var num = 145883
  691. if let localNum = UserDefaults.standard.value(forKey: QSLConfig.user_default_local_buy_count) as? Int {
  692. num = localNum
  693. }
  694. let randomAddCount = Int.random(in: 1...10)
  695. num = num + randomAddCount
  696. UserDefaults.standard.setValue(num, forKey: QSLConfig.user_default_local_buy_count)
  697. self.peopleCountLabel.text("\(num)人 已开通VIP")
  698. }
  699. }
  700. // MARK: - 设置 CollectionView
  701. extension QSLVipController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  702. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  703. return goodList.count - 1
  704. }
  705. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  706. let cell = collectionView.dequeueReusableCell(cellType: QSLVipGoodCollectionViewCell.self, cellForRowAt: indexPath)
  707. let model = self.goodList[indexPath.row + 1]
  708. if self.goodList.count - 1 == 2 {
  709. cell.config(model: model, type: .big)
  710. } else {
  711. cell.config(model: model, type: .small)
  712. }
  713. return cell
  714. }
  715. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  716. for i in 0..<self.goodList.count {
  717. self.goodList[i].isSelect = false
  718. }
  719. if self.goodList.count > 0 {
  720. self.goodList[indexPath.row + 1].isSelect = true
  721. self.selectGood = self.goodList[indexPath.row + 1]
  722. self.mostCell.config(model: self.goodList[0])
  723. //选中立即支付
  724. unlockBtnAction()
  725. }
  726. switch self.selectGood?.level {
  727. case 100 :
  728. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  729. break
  730. case 700:
  731. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  732. break;
  733. case 3100:
  734. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  735. break;
  736. case 9200:
  737. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  738. break;
  739. case 36600:
  740. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  741. break;
  742. case 3660000:
  743. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  744. break;
  745. default:
  746. break;
  747. }
  748. self.goodsCollectionView.reloadData()
  749. }
  750. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  751. var width = (QSLConst.qsl_kScreenW - 42.0.rpx) / 3.0
  752. if self.goodList.count - 1 == 2 {
  753. width = (QSLConst.qsl_kScreenW - 36.0.rpx) / 2.0
  754. }
  755. return CGSize(width: width, height: 134.0.rpx)
  756. }
  757. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  758. return 6.rpx
  759. }
  760. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  761. return 3.rpx
  762. }
  763. }
  764. extension QSLVipController {
  765. func updateUI() {
  766. if QSLBaseManager.shared.isLogin() && QSLBaseManager.shared.isVip() {
  767. let model = QSLBaseManager.shared.userModel.memberModel
  768. if model.permanent {
  769. self.vipTimeLabel.text("您已是尊贵的永久会员")
  770. self.bottomContentView.isHidden = true
  771. } else {
  772. let level = model.memberLevelString()
  773. let endTime = model.endTimestampString()
  774. self.vipTimeLabel.text("\(level):\(endTime)到期")
  775. }
  776. } else {
  777. self.vipTimeLabel.text("升级VIP会员,解锁全部功能")
  778. }
  779. }
  780. func updateSelectGoodUI() {
  781. var priceText = ""
  782. var originalPriceText = ""
  783. if let selectGood = self.selectGood {
  784. if selectGood.amount.truncatingRemainder(dividingBy: 100) == 0 {
  785. priceText = "\(Int(selectGood.amount / 100))"
  786. } else {
  787. priceText = String(format: "%.2lf", selectGood.amount / 100 )
  788. }
  789. if selectGood.originalAmount.truncatingRemainder(dividingBy: 100) == 0 {
  790. originalPriceText = "\(Int(selectGood.originalAmount / 100))"
  791. } else {
  792. originalPriceText = String(format: "%.2lf", selectGood.originalAmount / 100 )
  793. }
  794. }
  795. self.priceLabel.text(priceText)
  796. // self.goodTypeLabel.text("/ \(self.selectGood?.name ?? "")")
  797. self.goodOriginalPriceLabel.text("原价\(originalPriceText)")
  798. ///底部内容
  799. bottomTopLabelInfo(self.selectGood ?? QSLGoodModel())
  800. }
  801. func initializeView() {
  802. self.view.addSubview(vipBg)
  803. vipBg.snp.makeConstraints { make in
  804. make.left.top.right.equalTo(0)
  805. }
  806. self.view.addSubview(backButton)
  807. backButton.snp.makeConstraints { make in
  808. make.size.equalTo(100.rpx)
  809. make.height.equalTo(25.rpx)
  810. make.left.equalTo(12.rpx)
  811. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  812. }
  813. self.view.addSubview(peopleCountView)
  814. peopleCountView.snp.makeConstraints { make in
  815. make.size.equalTo(CGSize(width: 212.rpx, height: 24.rpx))
  816. make.right.equalTo(-13.rpx)
  817. make.centerY.equalTo(backButton.snp.centerY)
  818. }
  819. peopleCountView.addSubview(peopleAvatarImageView)
  820. peopleAvatarImageView.snp.makeConstraints { make in
  821. make.size.equalTo(CGSize(width: 72.rpx, height: 16.6.rpx))
  822. make.left.equalTo(3.rpx)
  823. make.centerY.equalTo(peopleCountView.snp.centerY)
  824. }
  825. peopleCountView.addSubview(peopleCountLabel)
  826. peopleCountLabel.snp.makeConstraints { make in
  827. make.left.equalTo(peopleAvatarImageView.snp.right).offset(7.rpx)
  828. make.centerY.equalTo(peopleCountView.snp.centerY)
  829. }
  830. self.view.addSubview(scrollView)
  831. scrollView.snp.makeConstraints { make in
  832. make.left.right.equalTo(0)
  833. make.top.equalTo(QSLConst.qsl_kNavFrameH)
  834. make.bottom.equalTo(0)
  835. }
  836. scrollView.addSubview(cardBannerImageView)
  837. cardBannerImageView.snp.makeConstraints { make in
  838. make.top.equalTo(0)
  839. make.centerX.equalToSuperview()
  840. make.width.equalTo(336.rpx)
  841. make.height.equalTo(108.rpx)
  842. }
  843. cardBannerImageView.addSubview(vipTimeLabel)
  844. vipTimeLabel.snp.makeConstraints { make in
  845. make.left.equalTo(23.rpx)
  846. make.bottom.equalTo(-19.rpx)
  847. }
  848. scrollView.addSubview(funcBannerImageView)
  849. funcBannerImageView.snp.makeConstraints { make in
  850. make.size.equalTo(CGSize(width: 336.rpx, height: 172.rpx))
  851. make.centerX.equalToSuperview()
  852. make.top.equalTo(cardBannerImageView.snp.bottom).offset(14.rpx)
  853. }
  854. scrollView.addSubview(mainView)
  855. mainView.snp.makeConstraints { make in
  856. make.left.right.equalTo(0)
  857. make.top.equalTo(funcBannerImageView.snp.bottom).offset(-24.rpx)
  858. make.width.equalTo(QSLConst.qsl_kScreenW)
  859. // make.height.equalTo(800.rpx)
  860. }
  861. let goodsBgHeight = 54.rpx + UX.mostCellHeight
  862. mainView.addSubview(goodsBgView)
  863. goodsBgView.snp.makeConstraints { make in
  864. make.top.left.right.equalTo(0)
  865. make.width.equalTo(QSLConst.qsl_kScreenW)
  866. make.height.equalTo(goodsBgHeight)
  867. }
  868. goodsBgView.addSubview(vipGoodsTitleIcon)
  869. vipGoodsTitleIcon.snp.makeConstraints { make in
  870. make.size.equalTo(CGSize(width: 117.rpx, height: 26.rpx))
  871. make.left.equalTo(20.rpx)
  872. make.top.equalTo(16.rpx)
  873. }
  874. goodsBgView.addSubview(resumeBtn)
  875. resumeBtn.snp.makeConstraints { make in
  876. make.size.equalTo(CGSize(width: 75.rpx, height: 16.rpx))
  877. make.right.equalTo(-18.rpx)
  878. make.centerY.equalTo(vipGoodsTitleIcon.snp.centerY)
  879. }
  880. goodsBgView.addSubview(mostCell)
  881. mostCell.snp.makeConstraints { make in
  882. make.left.equalTo(12.rpx)
  883. make.right.equalTo(-16.rpx)
  884. make.height.equalTo(113.rpx)
  885. make.top.equalTo(vipGoodsTitleIcon.snp.bottom).offset(10.rpx)
  886. }
  887. goodsBgView.addSubview(goodsCollectionView)
  888. goodsCollectionView.snp.makeConstraints { make in
  889. make.left.equalTo(12.rpx)
  890. make.right.equalTo(-18.rpx)
  891. make.bottom.equalTo(-20.rpx)
  892. make.top.equalTo(mostCell.snp.bottom).offset(3.rpx)
  893. }
  894. // goodsBgView.addSubview(selectBtn)
  895. // selectBtn.snp.makeConstraints { make in
  896. // make.size.equalTo(CGSize(width: 12.rpx, height: 12.rpx))
  897. // make.left.equalTo(23.rpx)
  898. // make.top.equalTo(goodsCollectionView.snp.bottom).offset(16.rpx)
  899. // }
  900. //
  901. // goodsBgView.addSubview(serviceLabel)
  902. // serviceLabel.snp.makeConstraints { make in
  903. // make.left.equalTo(selectBtn.snp.right).offset(2.rpx)
  904. // make.centerY.equalTo(selectBtn.snp.centerY)
  905. // }
  906. mainView.addSubview(commentView)
  907. commentView.snp.makeConstraints { make in
  908. make.left.right.equalTo(0)
  909. make.top.equalTo(goodsBgView.snp.bottom).offset(8.rpx)
  910. make.height.equalTo(525.rpx + QSLConst.qsl_kTabbarBottom)
  911. make.bottom.equalTo(0)
  912. }
  913. commentView.addSubview(commentTitleIcon)
  914. commentTitleIcon.snp.makeConstraints { make in
  915. make.size.equalTo(CGSize(width: 83.rpx, height: 26.rpx))
  916. make.top.equalTo(16.rpx)
  917. make.left.equalTo(12.rpx)
  918. }
  919. let commentHeight1 = "上班没时间,远程遛娃,非常方便很好用。".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  920. commentView.addSubview(comment1)
  921. comment1.snp.makeConstraints { make in
  922. make.left.right.equalTo(0)
  923. make.top.equalTo(commentTitleIcon.snp.bottom).offset(16.rpx)
  924. make.height.equalTo(commentHeight1)
  925. }
  926. let commentHeight2 = "用了之后,才发现真的可以找到他。".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  927. commentView.addSubview(comment2)
  928. comment2.snp.makeConstraints { make in
  929. make.left.right.equalTo(0)
  930. make.top.equalTo(comment1.snp.bottom).offset(30.rpx)
  931. make.height.equalTo(commentHeight2)
  932. }
  933. let commentHeight3 = "轨迹很准,一目了然,奶奶出门遇到危险直接一键报警,我就收到信息了".heightAccording(width: QSLConst.qsl_kScreenW - 52.rpx - 12.rpx, font: .textF(15), lineSpacing: 2) + 35.rpx
  934. commentView.addSubview(comment3)
  935. comment3.snp.makeConstraints { make in
  936. make.left.right.equalTo(0)
  937. make.top.equalTo(comment2.snp.bottom).offset(30.rpx)
  938. make.height.equalTo(commentHeight3)
  939. }
  940. // commentView.addSubview(tipTitleLabel)
  941. // tipTitleLabel.snp.makeConstraints { make in
  942. // make.left.equalTo(16)
  943. // make.top.equalTo(comment3.snp.bottom).offset(28)
  944. // }
  945. commentView.addSubview(tipContentLabel)
  946. tipContentLabel.snp.makeConstraints { make in
  947. make.left.equalTo(16)
  948. make.right.equalTo(-16)
  949. make.top.equalTo(comment3.snp.bottom).offset(11)
  950. }
  951. commentView.addSubview(serviceLabel)
  952. serviceLabel.snp.makeConstraints { make in
  953. make.left.equalTo(16)
  954. make.top.equalTo(tipContentLabel.snp.bottom).offset(28.rpx)
  955. }
  956. scrollView.snp.makeConstraints { make in
  957. make.bottom.equalTo(mainView)
  958. }
  959. self.view.addSubview(bottomContentView)
  960. bottomContentView.snp.makeConstraints { make in
  961. make.left.equalTo(12.rpx)
  962. make.right.equalTo(-12.rpx)
  963. make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom)
  964. make.height.equalTo(72.rpx)
  965. }
  966. bottomContentView.addSubview(bottomTopView)
  967. bottomTopView.snp.makeConstraints { make in
  968. make.left.equalToSuperview()
  969. make.right.equalToSuperview()
  970. make.top.equalToSuperview()
  971. make.height.equalTo(60.rpx)
  972. }
  973. bottomTopView.addSubview(bottomTopLabel)
  974. bottomTopLabel.snp.makeConstraints { make in
  975. make.left.equalToSuperview().offset(22)
  976. make.top.equalToSuperview()
  977. make.height.equalTo(21.rpx)
  978. }
  979. bottomContentView.addSubview(bottomView)
  980. bottomView.snp.makeConstraints { make in
  981. make.left.equalToSuperview()
  982. make.right.equalToSuperview()
  983. make.bottom.equalToSuperview()
  984. make.height.equalTo(50.rpx)
  985. }
  986. bottomView.addSubview(unlockBtn)
  987. unlockBtn.snp.makeConstraints { make in
  988. make.right.top.bottom.equalTo(0)
  989. make.width.equalTo(165.rpx)
  990. }
  991. bottomView.addSubview(priceIconLabel)
  992. priceIconLabel.snp.makeConstraints { make in
  993. make.left.equalTo(20.rpx)
  994. make.bottom.equalTo(-12.rpx)
  995. }
  996. bottomView.addSubview(priceLabel)
  997. priceLabel.snp.makeConstraints { make in
  998. make.left.equalTo(priceIconLabel.snp.right).offset(2.rpx)
  999. make.bottom.equalTo(-10.rpx)
  1000. }
  1001. bottomView.addSubview(goodTypeLabel)
  1002. goodTypeLabel.snp.makeConstraints { make in
  1003. make.left.equalTo(priceLabel.snp.right).offset(2.rpx)
  1004. make.bottom.equalTo(-14.rpx)
  1005. }
  1006. bottomView.addSubview(goodOriginalPriceLabel)
  1007. goodOriginalPriceLabel.snp.makeConstraints { make in
  1008. make.left.equalTo(goodTypeLabel.snp.right).offset(2.rpx)
  1009. make.centerY.equalTo(goodTypeLabel.snp.centerY)
  1010. }
  1011. }
  1012. }