QSLVipController.swift 48 KB

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