QSLActivityVipVC.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. //
  2. // QSLActivityVipVC.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2025/9/23.
  6. //
  7. import UIKit
  8. import GKCycleScrollView
  9. import YYText
  10. class QSLActivityVipVC: QSLBaseController {
  11. var goodList: [QSLGoodModel] = [QSLGoodModel]()
  12. var selectGood: QSLGoodModel?
  13. var currentCell: QSLVipMostGoodCell?
  14. var dismissHandler: ((Bool) -> Void)?
  15. var isCancel = false
  16. override func viewDidLoad() {
  17. super.viewDidLoad()
  18. gravityInstance?.track(QSLGravityConst.activity_vip_show, properties: [:])
  19. self.initializeView()
  20. self.requestNetwork()
  21. self.updateServiceLabelText(showSubscribe: false)
  22. }
  23. @objc func privacyAction() {
  24. let vc = QSLWebViewController()
  25. vc.webUrl = QSLConfig.AppPrivacyAgreementLink
  26. vc.title = "隐私政策"
  27. self.navigationController?.pushViewController(vc, animated: true)
  28. }
  29. @objc func serviceAction() {
  30. let vc = QSLWebViewController()
  31. vc.webUrl = QSLConfig.AppServiceAgreementLink
  32. vc.title = "服务协议"
  33. self.navigationController?.pushViewController(vc, animated: true)
  34. }
  35. @objc func subscibeAction() {
  36. let vc = QSLWebViewController()
  37. vc.webUrl = QSLConfig.AppSubscibeAgreementLink
  38. vc.title = "续订说明"
  39. self.navigationController?.pushViewController(vc, animated: true)
  40. }
  41. @objc func payBtnAction() {
  42. switch self.selectGood?.level {
  43. case 100 :
  44. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "day"])
  45. break
  46. case 700:
  47. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "weekly"])
  48. break;
  49. case 3100:
  50. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "monthly"])
  51. break;
  52. case 9200:
  53. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "quarterly"])
  54. break;
  55. case 36600:
  56. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "yearly"])
  57. break;
  58. case 3660000:
  59. gravityInstance?.track(QSLGravityConst.activity_vip_click, properties: ["package_type": "lifetime"])
  60. break;
  61. default:
  62. break;
  63. }
  64. let memberModel = QSLBaseManager.shared.userModel.memberModel
  65. if let subscriptionExpired = memberModel.subscriptionExpired, !subscriptionExpired {
  66. self.view.toast(text: "你已经订阅了")
  67. return
  68. }
  69. if goodList.count > 0, let selectGood = self.selectGood {
  70. QSLLoading.show()
  71. QSLVipManager.shared.startPay(goods: selectGood) { [self] status, outTradeNo in
  72. QSLVipManager.shared.isPaying = false
  73. if status == .success {
  74. QSLLoading.success(text: "支付成功")
  75. //弹出是否好评的弹窗
  76. QSLGuideusersToCommentManager.commentShare.manageWhetherTriggerPopUpWindow(QSLGuideusersToCommentType.member)
  77. // 引力传递支付事件
  78. if let selectGood = self.selectGood {
  79. gravityInstance?.trackPayEvent(withAmount: Int32(selectGood.amount), withPayType: "CNY", withOrderId: outTradeNo, withPayReason: selectGood.name, withPayMethod: "apple")
  80. }
  81. #if DEBUG
  82. #else
  83. //苹果广告奇异果传递支付事件
  84. QSWikiHandle.shared.addEventResultAttribution(eventDict: ["event_name": "pay", "event_val": selectGood.amount])
  85. #endif
  86. gravityInstance?.track(QSLGravityConst.activity_vip_result, properties: ["purchase_result": "success","pay_amount":Int32(selectGood.amount)])
  87. DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
  88. self.navigationController?.popViewController(animated: true)
  89. NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  90. }
  91. } else if status == .cancel {
  92. gravityInstance?.track(QSLGravityConst.activity_vip_result, properties: ["purchase_result": "cancel","pay_amount":Int32(selectGood.amount)])
  93. QSLLoading.error(text: "支付取消")
  94. // payFailAlertTip()
  95. self.isCancel = true
  96. } else if status == .fail {
  97. gravityInstance?.track(QSLGravityConst.activity_vip_result, properties: ["purchase_result": "fail","pay_amount":Int32(selectGood.amount)])
  98. gravityInstance?.track(QSLGravityConst.vip_fail)
  99. QSLLoading.error(text: "支付失败")
  100. // payFailAlertTip()
  101. self.isCancel = true
  102. } else if status == .searchFail {
  103. QSLLoading.error(text: "查询订单失败,请稍后重试")
  104. }
  105. }
  106. }
  107. }
  108. func payFailAlertTip() {
  109. // gravityInstance?.track(QSLGravityConst.activity_vip_retention_show, properties: ["trigger_type":"cancel_payment"])
  110. if let currentWindow = UIApplication.keyWindow {
  111. QSLRetainPopUpAlertView.alert(view: currentWindow, isOneBtn: true, oneBtnText: "继续支付", oneBtnClosure: { [weak self] in
  112. self?.payBtnAction()
  113. // gravityInstance?.track(QSLGravityConst.activity_vip_retention_click, properties: ["button":"continue_payment"])
  114. },secondBtnClosure: {
  115. // gravityInstance?.track(QSLGravityConst.activity_vip_retention_click, properties: ["button":"close"])
  116. })
  117. }
  118. }
  119. @objc func requestNetwork() {
  120. // 定义并赋值 itemListDict(根据条件变化)
  121. let itemListDict: [String: Any] = ["itemListType": 2]
  122. // 网络请求时使用 itemListDict 作为参数(关键修复)
  123. QSLNetwork().request(.vipActivityItemList(dict: itemListDict)) { response in
  124. // 后续逻辑不变...
  125. let list = response.mapArray(QSLGoodModel.self, modelKey: "data>list")
  126. self.goodList = list
  127. if self.goodList.count > 0 {
  128. self.goodList[0].isSelect = true
  129. self.selectGood = self.goodList[0]
  130. var height = 200.rpx
  131. if(self.goodList.count > 2){
  132. let row = (self.goodList.count-1)/2 + 1
  133. height = 124.rpx + row*124.rpx
  134. }
  135. self.vipItemView.snp.updateConstraints { make in
  136. make.height.equalTo(height)
  137. }
  138. self.scrollView.snp.makeConstraints { make in
  139. make.bottom.equalTo(self.vipItemView).offset(0)
  140. }
  141. QSLCountdownManager.shared.selectGood = self.goodList[0]
  142. QSLCountdownManager.shared.updateHandler1 = { [weak self] timeString in
  143. self?.countdownLabel.updateCountdownText(timeString)
  144. }
  145. QSLCountdownManager.shared.startCountdown()
  146. NotificationCenter.default.post(
  147. name: Notification.Name("QSLHomeUpdateCouponViewNoti"),
  148. object: nil,
  149. userInfo: ["showCoupon": true]
  150. )
  151. }
  152. self.goodsCollectionView.reloadData()
  153. } fail: { code, error in
  154. self.view.toast(text: "加载商品列表失败")
  155. }
  156. }
  157. override func backBtnAction() {
  158. self.dismissHandler?(self.isCancel)
  159. super.backBtnAction()
  160. }
  161. // 恢复按钮点击
  162. @objc func resumeBtnAction() {
  163. let memberModel = QSLBaseManager.shared.userModel.memberModel
  164. let expired = memberModel.expired
  165. if !expired {
  166. QSLLoading.success(text: "您已经在订阅中,无需恢复")
  167. return
  168. }
  169. QSLLoading.show()
  170. QSLVipManager.shared.restoreAction { isSuccess in
  171. QSLVipManager.shared.isPaying = false
  172. if isSuccess {
  173. QSLNetwork().request(.userMember(dict: [:])) { response in
  174. let model = response.mapObject(QSLMemberModel.self, modelKey: "data")
  175. QSLBaseManager.shared.userModel.memberModel = model
  176. if model.expired {
  177. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  178. } else {
  179. QSLBaseManager.shared.saveVipExpiredTime(time: model.endTimestamp)
  180. }
  181. QSLBaseManager.shared.saveUserId(id: model.userId)
  182. if model.endTimestamp > memberModel.endTimestamp {
  183. QSLLoading.success(text: "恢复成功")
  184. // 支付成功通知
  185. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  186. self.navigationController?.popViewController(animated: true)
  187. }
  188. } else {
  189. QSLLoading.error(text: "没有可供恢复的订阅")
  190. }
  191. } fail: { code, error in
  192. QSLLoading.error(text: "没有可供恢复的订阅")
  193. }
  194. } else {
  195. QSLLoading.error(text: "没有可供恢复的订阅")
  196. }
  197. }
  198. }
  199. // 更新服务条款文本内容
  200. func updateServiceLabelText(showSubscribe: Bool) {
  201. let attr = NSMutableAttributedString()
  202. // 固定部分:购买即同意
  203. let firstAttr = NSMutableAttributedString(string: "购买前请先阅读")
  204. firstAttr.font(11)
  205. firstAttr.color(UIColor.init(white: 0, alpha: 0.4))
  206. attr.append(firstAttr)
  207. // 《隐私权政策》
  208. let privacyHL = YYTextHighlight()
  209. let privacyStr = "隐私政策"
  210. let privacyText = NSMutableAttributedString(string: privacyStr)
  211. privacyText.font(11)
  212. privacyText.color(UIColor.init(white: 0, alpha: 0.7))
  213. privacyText.yy_setTextHighlight(privacyHL, range: NSRange(location: 0, length: privacyStr.count))
  214. privacyHL.tapAction = { [weak self] containerView, text, range, rect in
  215. self?.privacyAction()
  216. }
  217. let underline1 = YYTextDecoration(style: .single, width: 1, color: UIColor(white: 0, alpha: 0.7))
  218. privacyText.yy_textUnderline = underline1
  219. attr.append(privacyText)
  220. let blankAttr = NSMutableAttributedString(string: "&")
  221. blankAttr.color(UIColor.init(white: 0, alpha: 0.4))
  222. blankAttr.font(11)
  223. attr.append(blankAttr)
  224. // 《用户协议》
  225. let serviceHL = YYTextHighlight()
  226. let serviceStr = "服务条款"
  227. let serviceText = NSMutableAttributedString(string: serviceStr)
  228. serviceText.font(11)
  229. serviceText.color(UIColor.init(white: 0, alpha: 0.7))
  230. serviceText.yy_setTextHighlight(serviceHL, range: NSRange(location: 0, length: serviceStr.count))
  231. serviceHL.tapAction = { [weak self] containerView, text, range, rect in
  232. self?.serviceAction()
  233. }
  234. let underline = YYTextDecoration(style: .single, width: 1, color: UIColor(white: 0, alpha: 0.7))
  235. serviceText.yy_textUnderline = underline
  236. attr.append(serviceText)
  237. // 根据条件决定是否添加《续订说明》相关内容
  238. if showSubscribe {
  239. attr.append(blankAttr)
  240. let andAttr = NSMutableAttributedString(string: "和")
  241. andAttr.font(10)
  242. andAttr.color(.hexStringColor(hexString: "#A7A7A7"))
  243. attr.append(andAttr)
  244. attr.append(blankAttr)
  245. let subcribeHL = YYTextHighlight()
  246. let subcribeStr = "《续订说明》"
  247. let subcribeText = NSMutableAttributedString(string: subcribeStr)
  248. subcribeText.font(10)
  249. subcribeText.color(.hexStringColor(hexString: "#E7B983"))
  250. subcribeText.yy_setTextHighlight(subcribeHL, range: NSRange(location: 0, length: subcribeStr.count))
  251. subcribeHL.tapAction = { [weak self] containerView, text, range, rect in
  252. self?.subscibeAction()
  253. }
  254. attr.append(subcribeText)
  255. }
  256. serviceLabel.attributedText = attr
  257. serviceLabel.textAlignment = .center
  258. }
  259. lazy var scrollView: UIScrollView = {
  260. let scrollView = UIScrollView()
  261. // scrollView.delegate = self
  262. scrollView.bounces = false
  263. scrollView.showsVerticalScrollIndicator = false
  264. scrollView.contentInsetAdjustmentBehavior = .never
  265. return scrollView
  266. }()
  267. lazy var vipNaviView: UIView = {
  268. let view = UIView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW, QSLConst.qsl_kScreenH))
  269. view.addCorner(conrners: [.topLeft,.topRight], radius: 12.rpx)
  270. view.backgroundColor = UIColor.clear
  271. return view
  272. }()
  273. lazy var naviTitleIcon: UILabel = {
  274. let label = UILabel()
  275. label.text("超值优惠")
  276. label.textColor = .white
  277. label.mediumFont(17)
  278. return label
  279. }()
  280. lazy var naviResumeBtn: UIButton = {
  281. let button = UIButton()
  282. button.title("恢复购买")
  283. button.setTitleColor(.white, for: .normal)
  284. button.titleLabel?.font = UIFont.systemFont(ofSize: 11, weight: .medium)
  285. button.image(UIImage(named: "vip_resume_btn")?.withTintColor(UIColor.white))
  286. button.setImageTitleLayout(.imgLeft, spacing: 2.rpx)
  287. button.addTarget(self, action: #selector(resumeBtnAction), for: .touchUpInside)
  288. return button
  289. }()
  290. lazy var backButton: UIButton = {
  291. let button = UIButton()
  292. button.image(UIImage(named: "vip_pay_failure_close"))
  293. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  294. return button
  295. }()
  296. lazy var vipBg: UIView = {
  297. let imageView = UIView()
  298. return imageView
  299. }()
  300. lazy var vipTopBg: UIImageView = {
  301. let imageView = UIImageView()
  302. imageView.image = UIImage(named: "vip_activity_top_bg")
  303. return imageView
  304. }()
  305. lazy var vipTopTitleView: UIImageView = {
  306. let imageView = UIImageView()
  307. imageView.image = UIImage(named: "vip_activity_top_title")
  308. return imageView
  309. }()
  310. lazy var vipDiamondView: UIButton = {
  311. let button = UIButton()
  312. button.image(UIImage(named: "vip_activity_top_diamond"))
  313. button.title("会员限时福利")
  314. button.font(14)
  315. button.textColor(.white)
  316. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  317. button.isUserInteractionEnabled = false
  318. return button
  319. }()
  320. lazy var vipContentView: UIView = {
  321. let view = UIView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW, QSLConst.qsl_kScreenH))
  322. view.addCorner(conrners: [.topLeft,.topRight], radius: 12.rpx)
  323. view.backgroundColor = UIColor.white
  324. return view
  325. }()
  326. lazy var addTitleIcon: UILabel = {
  327. let label = UILabel()
  328. label.text("功能介绍")
  329. label.textColor = .hexStringColor(hexString: "#202020")
  330. label.boldFont(15)
  331. return label
  332. }()
  333. lazy var addTitleIconBg: UIView = {
  334. let view = UIView(frame: CGRectMake(0, 0, 117.rpx, 8.rpx))
  335. view.addRadius(radius: 4.rpx)
  336. // 创建渐变色层
  337. let gradientLayer = CAGradientLayer()
  338. gradientLayer.colors = [
  339. UIColor.hexStringColor(hexString: "#00DDAA",alpha: 1).cgColor,
  340. UIColor.hexStringColor(hexString: "#00DDAA",alpha: 0).cgColor
  341. ]
  342. gradientLayer.startPoint = CGPoint(x: 0, y: 0.4) // 左中
  343. gradientLayer.endPoint = CGPoint(x: 1, y: 0.4) // 右中
  344. gradientLayer.frame = view.bounds
  345. // 确保在布局变化时更新frame
  346. view.layer.insertSublayer(gradientLayer, at: 0)
  347. // 添加布局变化的监听
  348. view.layoutIfNeeded()
  349. view.layoutSubviews()
  350. return view
  351. }()
  352. lazy var cycleScrollView: GKCycleScrollView = {
  353. let cycleScrollView = GKCycleScrollView()
  354. cycleScrollView.dataSource = self
  355. cycleScrollView.delegate = self
  356. cycleScrollView.isAutoScroll = true
  357. cycleScrollView.isInfiniteLoop = true
  358. cycleScrollView.isChangeAlpha = false
  359. cycleScrollView.leftRightMargin = 12
  360. cycleScrollView.topBottomMargin = 12
  361. cycleScrollView.pageControl = pageControl
  362. cycleScrollView.reloadData()
  363. return cycleScrollView
  364. }()
  365. lazy var pageControl: GKPageControl = {
  366. let pageControl = GKPageControl()
  367. pageControl.style = .rectangle
  368. pageControl.dotHeight = 5.rpx
  369. pageControl.dotWidth = 5.rpx
  370. pageControl.dotMargin = 4.rpx
  371. pageControl.pageIndicatorTintColor = .hexStringColor(hexString: "#EEEEEE")
  372. pageControl.currentPageIndicatorTintColor = QSLColor.themeMainColor
  373. return pageControl
  374. }()
  375. lazy var vipItemView: UIView = {
  376. let item = UIView()
  377. return item
  378. }()
  379. lazy var goodsCollectionView: UICollectionView = {
  380. let layout = UICollectionViewFlowLayout()
  381. layout.minimumLineSpacing = 0
  382. layout.scrollDirection = .vertical
  383. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  384. collectionView.backgroundColor = .clear
  385. collectionView.dataSource = self
  386. collectionView.delegate = self
  387. collectionView.showsHorizontalScrollIndicator = false
  388. collectionView.bounces = false
  389. collectionView.register(cellClass: QSLActivityVipCell.self)
  390. return collectionView
  391. }()
  392. lazy var bottomView: UIView = {
  393. let view = UIView()
  394. view.backgroundColor = UIColor.white
  395. return view
  396. }()
  397. lazy var countdownView: UIView = {
  398. let view = UIView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW - 24.rpx, 47.rpx))
  399. view.addCorner(conrners: [.topLeft,.topRight], radius: 30.rpx)
  400. view.backgroundColor = .hexStringColor(hexString: "#FFFED8")
  401. return view
  402. }()
  403. lazy var countdownLabel: QSLCountdownView = {
  404. let label = QSLCountdownView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW - 24.rpx, 17.rpx),type: 2)
  405. return label
  406. }()
  407. lazy var unlockBtn: UIButton = {
  408. let btn = UIButton()
  409. btn.gradientBackgroundColor(color1: .hexStringColor(hexString: "#0E5E61"), color2: .hexStringColor(hexString: "#00434E"), width: QSLConst.qsl_kScreenW - 24.rpx, height: 50.rpx, direction: .horizontal)
  410. btn.addRadius(radius: 25.rpx)
  411. btn.title("立即解锁")
  412. btn.textColor(.hexStringColor(hexString: "#FFF8EF"))
  413. btn.mediumFont(18)
  414. btn.addTarget(self, action: #selector(payBtnAction), for: .touchUpInside)
  415. return btn
  416. }()
  417. lazy var serviceLabel: YYLabel = {
  418. let label = YYLabel()
  419. label.textAlignment = .center
  420. return label
  421. }()
  422. }
  423. extension QSLActivityVipVC{
  424. func initializeView() {
  425. self.view.addSubview(scrollView)
  426. scrollView.snp.makeConstraints { make in
  427. make.bottom.top.left.right.equalTo(0)
  428. }
  429. self.view.addSubview(vipNaviView)
  430. vipNaviView.snp.makeConstraints { make in
  431. make.top.left.right.equalTo(0)
  432. make.height.equalTo(QSLConst.qsl_kNavFrameH)
  433. }
  434. vipNaviView.addSubview(backButton)
  435. backButton.snp.makeConstraints { make in
  436. make.width.equalTo(44.rpx)
  437. make.height.equalTo(44.rpx)
  438. make.left.equalTo(10.rpx)
  439. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  440. }
  441. vipNaviView.addSubview(naviTitleIcon)
  442. naviTitleIcon.snp.makeConstraints { make in
  443. make.centerX.equalToSuperview()
  444. make.width.equalTo(70.rpx)
  445. make.height.equalTo(20.rpx)
  446. make.centerY.equalTo(backButton.snp.centerY)
  447. }
  448. vipNaviView.addSubview(naviResumeBtn)
  449. naviResumeBtn.snp.makeConstraints { make in
  450. make.size.equalTo(CGSize(width: 70.rpx, height: 18.rpx))
  451. make.right.equalTo(-8.rpx)
  452. make.centerY.equalTo(backButton.snp.centerY)
  453. }
  454. self.scrollView.addSubview(vipBg)
  455. vipBg.snp.makeConstraints { make in
  456. make.top.bottom.left.equalTo(0)
  457. make.width.equalTo(QSLConst.qsl_kScreenW)
  458. }
  459. vipBg.addSubview(vipTopBg)
  460. vipTopBg.snp.makeConstraints { make in
  461. make.left.top.right.equalTo(0)
  462. make.height.equalTo(185.rpx)
  463. }
  464. vipTopBg.addSubview(vipTopTitleView)
  465. vipTopTitleView.snp.makeConstraints { make in
  466. make.left.equalTo(16.rpx)
  467. make.bottom.equalTo(vipTopBg.snp.bottom).offset(-16.rpx)
  468. make.height.equalTo(22.rpx)
  469. make.width.equalTo(183.rpx)
  470. }
  471. vipTopBg.addSubview(vipDiamondView)
  472. vipDiamondView.snp.makeConstraints { make in
  473. make.left.equalTo(16.rpx)
  474. make.bottom.equalTo(vipTopTitleView.snp.top).offset(-6.rpx)
  475. make.height.equalTo(20.rpx)
  476. make.width.equalTo(105.rpx)
  477. }
  478. vipBg.addSubview(vipContentView)
  479. vipContentView.snp.makeConstraints { make in
  480. make.top.equalTo(185.rpx)
  481. make.left.right.equalTo(0.rpx)
  482. make.height.equalTo(QSLConst.qsl_kScreenH)
  483. }
  484. vipContentView.addSubview(addTitleIconBg)
  485. addTitleIconBg.snp.makeConstraints { make in
  486. make.size.equalTo(CGSize(width: 117.rpx, height: 8.rpx))
  487. make.left.equalTo(16.rpx)
  488. make.top.equalTo(26.rpx)
  489. }
  490. vipContentView.addSubview(addTitleIcon)
  491. addTitleIcon.snp.makeConstraints { make in
  492. make.size.equalTo(CGSize(width: 157.rpx, height: 26.rpx))
  493. make.left.equalTo(20.rpx)
  494. make.top.equalTo(12.rpx)
  495. }
  496. vipContentView.addSubview(cycleScrollView)
  497. cycleScrollView.snp.makeConstraints { make in
  498. make.left.right.equalTo(0)
  499. make.height.equalTo(150.rpx)
  500. make.top.equalTo(50.rpx)
  501. }
  502. vipContentView.addSubview(pageControl)
  503. pageControl.snp.makeConstraints { make in
  504. make.size.equalTo(CGSize(width: 68.rpx, height: 4.rpx))
  505. make.centerX.equalToSuperview()
  506. make.top.equalTo(cycleScrollView.snp.bottom).offset(17.rpx)
  507. }
  508. vipContentView.addSubview(vipItemView)
  509. vipItemView.snp.makeConstraints { make in
  510. make.left.right.equalTo(0)
  511. make.height.equalTo(150.rpx)
  512. make.top.equalTo(pageControl.snp.bottom).offset(16.rpx)
  513. }
  514. vipItemView.addSubview(goodsCollectionView)
  515. goodsCollectionView.snp.makeConstraints { make in
  516. make.left.right.top.bottom.equalTo(0)
  517. }
  518. self.view.addSubview(bottomView)
  519. bottomView.snp.makeConstraints { make in
  520. make.right.equalTo(-12.rpx)
  521. make.left.equalTo(12.rpx)
  522. make.height.equalTo(100.rpx)
  523. make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom/2)
  524. }
  525. bottomView.addSubview(countdownView)
  526. countdownView.snp.makeConstraints { make in
  527. make.right.left.top.equalTo(0)
  528. make.height.equalTo(47.rpx)
  529. }
  530. countdownView.addSubview(countdownLabel)
  531. countdownLabel.snp.makeConstraints { make in
  532. make.left.right.equalTo(0)
  533. make.top.equalTo(5.rpx)
  534. make.height.equalTo(17.rpx)
  535. }
  536. bottomView.addSubview(unlockBtn)
  537. unlockBtn.snp.makeConstraints { make in
  538. make.right.left.equalTo(0)
  539. make.height.equalTo(50.rpx)
  540. make.top.equalTo(25.rpx)
  541. }
  542. bottomView.addSubview(serviceLabel)
  543. serviceLabel.snp.makeConstraints { make in
  544. make.right.left.equalTo(0)
  545. make.height.equalTo(17.rpx)
  546. make.bottom.equalTo(0)
  547. }
  548. }
  549. }
  550. extension QSLActivityVipVC : GKCycleScrollViewDelegate, GKCycleScrollViewDataSource{
  551. func cycleScrollView(_ cycleScrollView: GKCycleScrollView!, cellForViewAt index: Int) -> GKCycleScrollViewCell! {
  552. if let cell = cycleScrollView.dequeueReusableCell() {
  553. cell.imageView.image = UIImage(named: "vip_activity_banner_\(index+1)")
  554. return cell
  555. }
  556. let cell = GKCycleScrollViewCell()
  557. cell.imageView.image = UIImage(named: "vip_activity_banner_\(index+1)")
  558. return cell
  559. }
  560. func numberOfCells(in cycleScrollView: GKCycleScrollView!) -> Int {
  561. return 3
  562. }
  563. func sizeForCell(in cycleScrollView: GKCycleScrollView!) -> CGSize {
  564. return CGSizeMake(QSLConst.qsl_kScreenW - 90.rpx, 150.rpx);
  565. }
  566. }
  567. extension QSLActivityVipVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  568. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  569. return goodList.count
  570. }
  571. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  572. let cell = collectionView.dequeueReusableCell(cellType: QSLActivityVipCell.self, cellForRowAt: indexPath)
  573. let model = self.goodList[indexPath.row]
  574. if (indexPath.row == 0) {
  575. cell.config(model: model, type: .top)
  576. } else {
  577. if(self.goodList.count > 2){
  578. cell.config(model: model, type: .small)
  579. }else{
  580. cell.config(model: model, type: .big)
  581. }
  582. }
  583. return cell
  584. }
  585. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  586. var list = [QSLGoodModel]()
  587. for index in 0..<self.goodList.count{
  588. var submodel = self.goodList[index]
  589. if(indexPath.row == index){
  590. submodel.isSelect = true
  591. self.selectGood = submodel
  592. }else{
  593. submodel.isSelect = false
  594. }
  595. list.append(submodel)
  596. }
  597. self.goodList = list
  598. self.goodsCollectionView.reloadData()
  599. self.payBtnAction()
  600. }
  601. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  602. if (indexPath.row == 0) {
  603. return CGSize(width: QSLConst.qsl_kScreenW-32.rpx, height: 112.rpx)
  604. } else {
  605. if(self.goodList.count == 2){
  606. return CGSize(width: QSLConst.qsl_kScreenW-32.rpx, height: 72.rpx)
  607. }else{
  608. return CGSize(width: (QSLConst.qsl_kScreenW-50.rpx)/2.0, height: 112.rpx)
  609. }
  610. }
  611. }
  612. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
  613. return UIEdgeInsets(top: 0, left: 16.rpx, bottom: 0, right: 16.rpx)
  614. }
  615. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  616. return 10.rpx
  617. }
  618. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  619. if(self.goodList.count == 2){
  620. return 10.rpx
  621. }else{
  622. return 16.rpx
  623. }
  624. }
  625. }