QSLVipController.swift 47 KB

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