QSLActivityVipController.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. //
  2. // QSLActivityVipController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2025/9/23.
  6. //
  7. import UIKit
  8. class QSLActivityVipController: QSLBaseController {
  9. // 购买人数
  10. static let record_non_member_clicks_to_claim = "RECORD_NON_MEMBER_CLIKS_CLAIM"
  11. struct UX {
  12. static let mostCellHeight = 113.0.rpx
  13. static let collectionRowHeight = 137.0.rpx
  14. static let goodsBgHeight = 54.rpx + UX.mostCellHeight + 20.rpx
  15. }
  16. var type: QSLVipJumpType?
  17. var goodList: [QSLGoodModel] = [QSLGoodModel]()
  18. ///是否是订阅的产品
  19. //var is
  20. var selectGood: QSLGoodModel? {
  21. didSet {
  22. updateSelectGoodUI()
  23. }
  24. }
  25. lazy var vipBg: UIImageView = {
  26. let imageView = UIImageView()
  27. imageView.image = UIImage(named: "vip_bg")
  28. return imageView
  29. }()
  30. lazy var backButton: UIButton = {
  31. let button = UIButton()
  32. button.image(UIImage(named: "public_back_btn_white"))
  33. button.title("会员中心")
  34. button.mediumFont(17)
  35. button.textColor(.white)
  36. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  37. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  38. return button
  39. }()
  40. lazy var peopleCountView: UIView = {
  41. let view = UIView()
  42. view.layer.cornerRadius = 12.rpx
  43. view.layer.borderColor = UIColor.white.withAlphaComponent(0.16).cgColor
  44. view.layer.borderWidth = 1.rpx
  45. return view
  46. }()
  47. lazy var peopleAvatarImageView: UIImageView = {
  48. let imageView = UIImageView()
  49. imageView.image = UIImage(named: "vip_avatars_icon")
  50. return imageView
  51. }()
  52. lazy var peopleCountLabel: UILabel = {
  53. let label = UILabel()
  54. label.text("1456488人 已开通VIP")
  55. label.color("#FFE6C0")
  56. label.font(12)
  57. return label
  58. }()
  59. lazy var scrollView: UIScrollView = {
  60. let scrollView = UIScrollView()
  61. // scrollView.delegate = self
  62. scrollView.bounces = false
  63. scrollView.showsVerticalScrollIndicator = false
  64. scrollView.contentInsetAdjustmentBehavior = .never
  65. return scrollView
  66. }()
  67. lazy var cardBannerImageView: UIImageView = {
  68. let imageView = UIImageView()
  69. imageView.image = UIImage(named: "vip_banner_card")
  70. return imageView
  71. }()
  72. lazy var vipTimeLabel: UILabel = {
  73. let label = UILabel()
  74. label.text("升级VIP会员,解锁全部功能")
  75. label.font(13)
  76. label.textColor = .hexStringColor(hexString: "#AF7655")
  77. return label
  78. }()
  79. lazy var funcBannerImageView: UIImageView = {
  80. let imageView = UIImageView()
  81. imageView.image = UIImage(named: "vip_banner_func")
  82. return imageView
  83. }()
  84. lazy var mainView: UIView = {
  85. let view = UIView()
  86. view.backgroundColor = QSLColor.backGroundColor
  87. view.addRadius(radius: 12.rpx)
  88. return view
  89. }()
  90. lazy var goodsBgView: UIView = {
  91. let view = UIView()
  92. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FFF8F2"), color2: .hexStringColor(hexString: "#FFFFFF"), width: QSLConst.qsl_kScreenW, height: UX.goodsBgHeight, direction: .vertical)
  93. return view
  94. }()
  95. lazy var vipGoodsTitleIcon: UIImageView = {
  96. let imageView = UIImageView()
  97. imageView.image = UIImage(named: "vip_title_icon")
  98. return imageView
  99. }()
  100. lazy var resumeBtn: UIButton = {
  101. let button = UIButton()
  102. button.title("恢复购买")
  103. button.setTitleColor(.hexStringColor(hexString: "#000000").withAlphaComponent(0.5), for: .normal)
  104. button.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: .medium)
  105. button.image(UIImage(named: "vip_resume_btn"))
  106. button.setImageTitleLayout(.imgLeft, spacing: 2.rpx)
  107. button.addTarget(self, action: #selector(resumeBtnAction), for: .touchUpInside)
  108. return button
  109. }()
  110. lazy var mostCell: QSLVipMostGoodCell = {
  111. let cell = QSLVipMostGoodCell()
  112. cell.isUserInteractionEnabled = true
  113. let tap = UITapGestureRecognizer(target: self, action: #selector(firstCellClickAction))
  114. cell.addGestureRecognizer(tap)
  115. return cell
  116. }()
  117. lazy var goodsCollectionView: UICollectionView = {
  118. let layout = UICollectionViewFlowLayout()
  119. layout.minimumLineSpacing = 0
  120. layout.scrollDirection = .vertical
  121. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  122. collectionView.backgroundColor = .clear
  123. collectionView.dataSource = self
  124. collectionView.delegate = self
  125. collectionView.showsHorizontalScrollIndicator = false
  126. collectionView.bounces = false
  127. collectionView.register(cellClass: QSLVipGoodCollectionViewCell.self)
  128. return collectionView
  129. }()
  130. lazy var selectBtn: UIButton = {
  131. let btn = UIButton()
  132. btn.image(UIImage(named: "public_select_btn_false"), .normal)
  133. btn.image(UIImage(named: "public_select_btn_true"), .selected)
  134. btn.addTarget(self, action: #selector(selectBtnAction), for: .touchUpInside)
  135. return btn
  136. }()
  137. lazy var bottomContentView: UIView = {
  138. let view = UIView()
  139. return view
  140. }()
  141. lazy var bottomTopView: UIView = {
  142. let view = UIView()
  143. view.isHidden = true
  144. view.backgroundColor = .hexStringColor(hexString: "#FFFED8")
  145. view.addRadius(radius: 30.rpx)
  146. return view
  147. }()
  148. lazy var bottomTopLabel: UILabel = {
  149. let label = UILabel()
  150. label.text = ""
  151. return label
  152. }()
  153. func bottomTopLabelInfo(_ goodInfo : QSLGoodModel) {
  154. let darkGrayAttributes: [NSAttributedString.Key: Any] = [
  155. .foregroundColor: UIColor.hexStringColor(hexString: "#404040"),
  156. .font: UIFont.systemFont(ofSize: 11),
  157. .paragraphStyle: {
  158. let paragraphStyle = NSMutableParagraphStyle()
  159. paragraphStyle.alignment = .center
  160. return paragraphStyle
  161. }(),
  162. .kern: -1
  163. ]
  164. // 创建绿色文本样式
  165. let greenAttributes: [NSAttributedString.Key: Any] = [
  166. .foregroundColor: UIColor.hexStringColor(hexString: "#EE6C1C"),
  167. .font: UIFont.systemFont(ofSize: 15, weight: .black),
  168. .paragraphStyle: {
  169. let paragraphStyle = NSMutableParagraphStyle()
  170. paragraphStyle.alignment = .center
  171. return paragraphStyle
  172. }(),
  173. .kern: -1
  174. ]
  175. let textArray = goodInfo.text.components(separatedBy: goodInfo.keys.key)
  176. if textArray.count > 0 && goodInfo.text.count > 0{
  177. bottomTopView.isHidden = false
  178. let inputtr = NSMutableAttributedString()
  179. let titleOneAttr = NSAttributedString(string: textArray.first ?? "", attributes: darkGrayAttributes)
  180. let titleTwoAttr = NSAttributedString(string: " \(goodInfo.keys.value) ", attributes: greenAttributes)
  181. inputtr.append(titleOneAttr)
  182. inputtr.append(titleTwoAttr)
  183. if textArray.count > 1 {
  184. let titleThreeAttr = NSAttributedString(string: textArray[1], attributes: darkGrayAttributes)
  185. inputtr.append(titleThreeAttr)
  186. }
  187. bottomTopLabel.attributedText = inputtr
  188. } else {
  189. bottomTopView.isHidden = true
  190. }
  191. }
  192. lazy var bottomView: UIView = {
  193. let view = UIView()
  194. view.gradientBackgroundColor(color1: .hexStringColor(hexString: "#00434E"), color2: .hexStringColor(hexString: "#0E5E61"), width: QSLConst.qsl_kScreenW - 24.rpx, height: 50.rpx, direction: .horizontal)
  195. view.addRadius(radius: 25.rpx)
  196. return view
  197. }()
  198. lazy var unlockBtn: UIButton = {
  199. let btn = UIButton()
  200. btn.setBackgroundImage(UIImage(named: "vip_unlock_btn_bg"), for: .normal)
  201. btn.title("立即解锁")
  202. btn.textColor(.hexStringColor(hexString: "#9B3800"))
  203. btn.mediumFont(18)
  204. btn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 30.rpx, bottom: 0, right: 0)
  205. btn.addTarget(self, action: #selector(unlockBtnAction), for: .touchUpInside)
  206. return btn
  207. }()
  208. lazy var priceIconLabel: UILabel = {
  209. let label = UILabel()
  210. label.text("¥")
  211. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  212. label.font(14)
  213. return label
  214. }()
  215. lazy var priceLabel: UILabel = {
  216. let label = UILabel()
  217. label.text("168")
  218. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  219. label.font(24)
  220. return label
  221. }()
  222. lazy var goodTypeLabel: UILabel = {
  223. let label = UILabel()
  224. label.text("/")
  225. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  226. label.font(12)
  227. return label
  228. }()
  229. lazy var goodOriginalPriceLabel: UILabel = {
  230. let label = UILabel()
  231. label.text("原价228")
  232. label.textColor = .hexStringColor(hexString: "#FFF8EF")
  233. label.font(12)
  234. label.centerLineText(lineValue: 1, underlineColor: .hexStringColor(hexString: "#FFF8EF"))
  235. return label
  236. }()
  237. override func viewDidLoad() {
  238. super.viewDidLoad()
  239. initializeView()
  240. updateUI()
  241. requestItemList()
  242. calculateBuyCount()
  243. if let type = self.type {
  244. switch type {
  245. case .homeRoad:
  246. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1001])
  247. case .add:
  248. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1002])
  249. case .friendRoad:
  250. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1003])
  251. case .contact:
  252. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1004])
  253. case .mine:
  254. gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1006])
  255. case .guideComments:
  256. print("")
  257. }
  258. }
  259. }
  260. }
  261. extension QSLActivityVipController {
  262. @objc func privacyAction() {
  263. let vc = QSLWebViewController()
  264. vc.webUrl = QSLConfig.AppPrivacyAgreementLink
  265. vc.title = "隐私政策"
  266. self.navigationController?.pushViewController(vc, animated: true)
  267. }
  268. @objc func serviceAction() {
  269. let vc = QSLWebViewController()
  270. vc.webUrl = QSLConfig.AppServiceAgreementLink
  271. vc.title = "服务协议"
  272. self.navigationController?.pushViewController(vc, animated: true)
  273. }
  274. @objc func subscibeAction() {
  275. let vc = QSLWebViewController()
  276. vc.webUrl = QSLConfig.AppSubscibeAgreementLink
  277. vc.title = "续订说明"
  278. self.navigationController?.pushViewController(vc, animated: true)
  279. }
  280. @objc func selectBtnAction() {
  281. selectBtn.isSelected = !selectBtn.isSelected
  282. }
  283. // 恢复按钮点击
  284. @objc func resumeBtnAction() {
  285. let memberModel = QSLBaseManager.shared.userModel.memberModel
  286. let expired = memberModel.expired
  287. if !expired {
  288. QSLLoading.success(text: "您已经在订阅中,无需恢复")
  289. return
  290. }
  291. QSLLoading.show()
  292. QSLVipManager.shared.restoreAction { isSuccess in
  293. QSLVipManager.shared.isPaying = false
  294. if isSuccess {
  295. QSLNetwork().request(.userMember(dict: [:])) { response in
  296. let model = response.mapObject(QSLMemberModel.self, modelKey: "data")
  297. QSLBaseManager.shared.userModel.memberModel = model
  298. if model.expired {
  299. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  300. } else {
  301. QSLBaseManager.shared.saveVipExpiredTime(time: model.endTimestamp)
  302. }
  303. QSLBaseManager.shared.saveUserId(id: model.userId)
  304. if model.endTimestamp > memberModel.endTimestamp {
  305. QSLLoading.success(text: "恢复成功")
  306. // 支付成功通知
  307. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  308. self.navigationController?.popViewController(animated: true)
  309. }
  310. } else {
  311. QSLLoading.error(text: "没有可供恢复的订阅")
  312. }
  313. } fail: { code, error in
  314. QSLLoading.error(text: "没有可供恢复的订阅")
  315. }
  316. } else {
  317. QSLLoading.error(text: "没有可供恢复的订阅")
  318. }
  319. }
  320. }
  321. // 支付按钮点击
  322. @objc func unlockBtnAction() {
  323. switch self.selectGood?.level {
  324. case 100 :
  325. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1006])
  326. break
  327. case 700:
  328. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1005])
  329. break;
  330. case 3100:
  331. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1004])
  332. break;
  333. case 9200:
  334. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1003])
  335. break;
  336. case 36600:
  337. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1002])
  338. break;
  339. case 3660000:
  340. gravityInstance?.track(QSLGravityConst.vip_buy_click, properties: ["id": 1001])
  341. break;
  342. default:
  343. break;
  344. }
  345. // if !selectBtn.isSelected {
  346. // self.view.toast(text: "请先同意《隐私权政策》和《用户协议》")
  347. // return
  348. // }
  349. let memberModel = QSLBaseManager.shared.userModel.memberModel
  350. if let subscriptionExpired = memberModel.subscriptionExpired, !subscriptionExpired {
  351. self.view.toast(text: "你已经订阅了")
  352. return
  353. }
  354. if goodList.count > 0, let selectGood = self.selectGood {
  355. QSLLoading.show()
  356. QSLVipManager.shared.startPay(goods: selectGood) { [self] status, outTradeNo in
  357. QSLVipManager.shared.isPaying = false
  358. if status == .success {
  359. QSLLoading.success(text: "支付成功")
  360. //支付成功埋点
  361. gravityInstance?.track(QSLGravityConst.vip_submit_success, properties: ["id": 01001])
  362. //弹出是否好评的弹窗
  363. QSLGuideusersToCommentManager.commentShare.manageWhetherTriggerPopUpWindow(QSLGuideusersToCommentType.member)
  364. // 引力传递支付事件
  365. if let selectGood = self.selectGood {
  366. gravityInstance?.trackPayEvent(withAmount: Int32(selectGood.amount), withPayType: "CNY", withOrderId: outTradeNo, withPayReason: selectGood.name, withPayMethod: "apple")
  367. }
  368. #if DEBUG
  369. #else
  370. //苹果广告奇异果传递支付事件
  371. QSWikiHandle.shared.addEventResultAttribution(eventDict: ["event_name": "pay", "event_val": selectGood.amount])
  372. #endif
  373. if let type = self.type {
  374. switch type {
  375. case .homeRoad:
  376. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1001])
  377. case .add:
  378. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1002])
  379. case .friendRoad:
  380. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1003])
  381. case .contact:
  382. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1004])
  383. case .mine:
  384. gravityInstance?.track(QSLGravityConst.vip_success_page, properties: ["id": 1006])
  385. case .guideComments:
  386. print("")
  387. }
  388. }
  389. switch self.selectGood?.level {
  390. case 100 :
  391. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 1])
  392. break
  393. case 700:
  394. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 5])
  395. break;
  396. case 3100:
  397. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 9])
  398. break;
  399. case 9200:
  400. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 13])
  401. break;
  402. case 36600:
  403. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 17])
  404. break;
  405. case 3660000:
  406. gravityInstance?.track(QSLGravityConst.vip_success_good, properties: ["id": 21])
  407. break;
  408. default:
  409. break;
  410. }
  411. DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
  412. self.navigationController?.popViewController(animated: true)
  413. NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  414. }
  415. } else if status == .cancel {
  416. QSLLoading.error(text: "支付取消")
  417. payFailAlertTip()
  418. } else if status == .fail {
  419. gravityInstance?.track(QSLGravityConst.vip_fail)
  420. QSLLoading.error(text: "支付失败")
  421. payFailAlertTip()
  422. } else if status == .searchFail {
  423. QSLLoading.error(text: "查询订单失败,请稍后重试")
  424. }
  425. }
  426. }
  427. }
  428. func payFailAlertTip() {
  429. if let currentWindow = UIApplication.keyWindow {
  430. QSLRetainPopUpAlertView.alert(view: currentWindow, isOneBtn: true, oneBtnText: "继续支付", oneBtnClosure: { [weak self] in
  431. self?.unlockBtnAction()
  432. })
  433. }
  434. }
  435. @objc func firstCellClickAction() {
  436. for i in 0..<self.goodList.count {
  437. self.goodList[i].isSelect = false
  438. }
  439. if self.goodList.count > 0 {
  440. self.goodList[0].isSelect = true
  441. self.selectGood = self.goodList[0]
  442. self.mostCell.config(model: self.goodList[0])
  443. //选中立即支付
  444. unlockBtnAction()
  445. }
  446. switch self.selectGood?.level {
  447. case 100 :
  448. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  449. break
  450. case 700:
  451. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  452. break;
  453. case 3100:
  454. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  455. break;
  456. case 9200:
  457. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  458. break;
  459. case 36600:
  460. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  461. break;
  462. case 3660000:
  463. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  464. break;
  465. default:
  466. break;
  467. }
  468. self.goodsCollectionView.reloadData()
  469. }
  470. }
  471. extension QSLActivityVipController {
  472. // 请求商品列表
  473. func requestItemList() {
  474. // 定义并赋值 itemListDict(根据条件变化)
  475. var itemListDict: [String: Any] = ["itemListType": 2]
  476. if UserDefaults.standard.string(forKey: QSLActivityVipController.record_non_member_clicks_to_claim) == nil && self.type == .guideComments {
  477. itemListDict = ["itemListType": 2, "showExtraText": true]
  478. // 记录非会员点击领取
  479. UserDefaults.standard.set("YES", forKey: QSLActivityVipController.record_non_member_clicks_to_claim)
  480. UserDefaults.standard.synchronize()
  481. }
  482. // 网络请求时使用 itemListDict 作为参数(关键修复)
  483. QSLNetwork().request(.vipItemList(dict: itemListDict)) { response in
  484. // 后续逻辑不变...
  485. let list = response.mapArray(QSLGoodModel.self, modelKey: "data>list")
  486. self.goodList = list
  487. if self.goodList.count > 0 {
  488. self.goodList[0].isSelect = true
  489. self.selectGood = self.goodList[0]
  490. self.mostCell.config(model: self.goodList[0])
  491. let row = ceil(Double(self.goodList.count - 1) / 3.0)
  492. let height = UX.goodsBgHeight + (row * UX.collectionRowHeight)
  493. self.goodsBgView.gradientBackgroundColor(color1: .hexStringColor(hexString: "#FFF8F2"), color2: .hexStringColor(hexString: "#FFFFFF"), width: QSLConst.qsl_kScreenW, height: height, direction: .vertical)
  494. self.goodsBgView.snp.updateConstraints { make in
  495. make.height.equalTo(height)
  496. }
  497. self.scrollView.snp.makeConstraints { make in
  498. make.bottom.equalTo(self.mainView)
  499. }
  500. self.checkRenewalOfProducts()
  501. }
  502. self.goodsCollectionView.reloadData()
  503. } fail: { code, error in
  504. self.view.toast(text: "加载商品列表失败")
  505. }
  506. }
  507. ///检查有没有续订的产品
  508. func checkRenewalOfProducts() {
  509. let hasSubscribable = self.goodList.contains(where: { model in
  510. return model.subscribable == 1
  511. })
  512. }
  513. // 计算购买人数
  514. func calculateBuyCount() {
  515. var num = 145883
  516. if let localNum = UserDefaults.standard.value(forKey: QSLConfig.user_default_local_buy_count) as? Int {
  517. num = localNum
  518. }
  519. let randomAddCount = Int.random(in: 1...10)
  520. num = num + randomAddCount
  521. UserDefaults.standard.setValue(num, forKey: QSLConfig.user_default_local_buy_count)
  522. self.peopleCountLabel.text("\(num)人 已开通VIP")
  523. }
  524. }
  525. // MARK: - 设置 CollectionView
  526. extension QSLActivityVipController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  527. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  528. return goodList.count - 1
  529. }
  530. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  531. let cell = collectionView.dequeueReusableCell(cellType: QSLVipGoodCollectionViewCell.self, cellForRowAt: indexPath)
  532. let model = self.goodList[indexPath.row + 1]
  533. if self.goodList.count - 1 == 2 {
  534. cell.config(model: model, type: .big)
  535. } else {
  536. cell.config(model: model, type: .small)
  537. }
  538. return cell
  539. }
  540. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  541. for i in 0..<self.goodList.count {
  542. self.goodList[i].isSelect = false
  543. }
  544. if self.goodList.count > 0 {
  545. self.goodList[indexPath.row + 1].isSelect = true
  546. self.selectGood = self.goodList[indexPath.row + 1]
  547. self.mostCell.config(model: self.goodList[0])
  548. //选中立即支付
  549. unlockBtnAction()
  550. }
  551. switch self.selectGood?.level {
  552. case 100 :
  553. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  554. break
  555. case 700:
  556. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  557. break;
  558. case 3100:
  559. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  560. break;
  561. case 9200:
  562. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  563. break;
  564. case 36600:
  565. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  566. break;
  567. case 3660000:
  568. gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  569. break;
  570. default:
  571. break;
  572. }
  573. self.goodsCollectionView.reloadData()
  574. }
  575. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  576. var width = (QSLConst.qsl_kScreenW - 42.0.rpx) / 3.0
  577. if self.goodList.count - 1 == 2 {
  578. width = (QSLConst.qsl_kScreenW - 36.0.rpx) / 2.0
  579. }
  580. return CGSize(width: width, height: 134.0.rpx)
  581. }
  582. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  583. return 6.rpx
  584. }
  585. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  586. return 3.rpx
  587. }
  588. }
  589. extension QSLActivityVipController {
  590. func updateUI() {
  591. if QSLBaseManager.shared.isLogin() && QSLBaseManager.shared.isVip() {
  592. let model = QSLBaseManager.shared.userModel.memberModel
  593. if model.permanent {
  594. self.vipTimeLabel.text("您已是尊贵的永久会员")
  595. self.bottomContentView.isHidden = true
  596. } else {
  597. let level = model.memberLevelString()
  598. let endTime = model.endTimestampString()
  599. self.vipTimeLabel.text("\(level):\(endTime)到期")
  600. }
  601. } else {
  602. self.vipTimeLabel.text("升级VIP会员,解锁全部功能")
  603. }
  604. }
  605. func updateSelectGoodUI() {
  606. var priceText = ""
  607. var originalPriceText = ""
  608. if let selectGood = self.selectGood {
  609. if selectGood.amount.truncatingRemainder(dividingBy: 100) == 0 {
  610. priceText = "\(Int(selectGood.amount / 100))"
  611. } else {
  612. priceText = String(format: "%.2lf", selectGood.amount / 100 )
  613. }
  614. if selectGood.originalAmount.truncatingRemainder(dividingBy: 100) == 0 {
  615. originalPriceText = "\(Int(selectGood.originalAmount / 100))"
  616. } else {
  617. originalPriceText = String(format: "%.2lf", selectGood.originalAmount / 100 )
  618. }
  619. }
  620. self.priceLabel.text(priceText)
  621. // self.goodTypeLabel.text("/ \(self.selectGood?.name ?? "")")
  622. self.goodOriginalPriceLabel.text("原价\(originalPriceText)")
  623. ///底部内容
  624. bottomTopLabelInfo(self.selectGood ?? QSLGoodModel())
  625. }
  626. func initializeView() {
  627. self.view.addSubview(vipBg)
  628. vipBg.snp.makeConstraints { make in
  629. make.left.top.right.equalTo(0)
  630. }
  631. self.view.addSubview(backButton)
  632. backButton.snp.makeConstraints { make in
  633. make.size.equalTo(100.rpx)
  634. make.height.equalTo(25.rpx)
  635. make.left.equalTo(12.rpx)
  636. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  637. }
  638. self.view.addSubview(peopleCountView)
  639. peopleCountView.snp.makeConstraints { make in
  640. make.size.equalTo(CGSize(width: 212.rpx, height: 24.rpx))
  641. make.right.equalTo(-13.rpx)
  642. make.centerY.equalTo(backButton.snp.centerY)
  643. }
  644. peopleCountView.addSubview(peopleAvatarImageView)
  645. peopleAvatarImageView.snp.makeConstraints { make in
  646. make.size.equalTo(CGSize(width: 72.rpx, height: 16.6.rpx))
  647. make.left.equalTo(3.rpx)
  648. make.centerY.equalTo(peopleCountView.snp.centerY)
  649. }
  650. peopleCountView.addSubview(peopleCountLabel)
  651. peopleCountLabel.snp.makeConstraints { make in
  652. make.left.equalTo(peopleAvatarImageView.snp.right).offset(7.rpx)
  653. make.centerY.equalTo(peopleCountView.snp.centerY)
  654. }
  655. self.view.addSubview(scrollView)
  656. scrollView.snp.makeConstraints { make in
  657. make.left.right.equalTo(0)
  658. make.top.equalTo(QSLConst.qsl_kNavFrameH)
  659. make.bottom.equalTo(0)
  660. }
  661. scrollView.addSubview(cardBannerImageView)
  662. cardBannerImageView.snp.makeConstraints { make in
  663. make.top.equalTo(0)
  664. make.centerX.equalToSuperview()
  665. make.width.equalTo(336.rpx)
  666. make.height.equalTo(108.rpx)
  667. }
  668. cardBannerImageView.addSubview(vipTimeLabel)
  669. vipTimeLabel.snp.makeConstraints { make in
  670. make.left.equalTo(23.rpx)
  671. make.bottom.equalTo(-19.rpx)
  672. }
  673. scrollView.addSubview(funcBannerImageView)
  674. funcBannerImageView.snp.makeConstraints { make in
  675. make.size.equalTo(CGSize(width: 336.rpx, height: 172.rpx))
  676. make.centerX.equalToSuperview()
  677. make.top.equalTo(cardBannerImageView.snp.bottom).offset(14.rpx)
  678. }
  679. scrollView.addSubview(mainView)
  680. mainView.snp.makeConstraints { make in
  681. make.left.right.equalTo(0)
  682. make.top.equalTo(funcBannerImageView.snp.bottom).offset(-24.rpx)
  683. make.width.equalTo(QSLConst.qsl_kScreenW)
  684. // make.height.equalTo(800.rpx)
  685. }
  686. let goodsBgHeight = 54.rpx + UX.mostCellHeight
  687. mainView.addSubview(goodsBgView)
  688. goodsBgView.snp.makeConstraints { make in
  689. make.top.left.right.equalTo(0)
  690. make.width.equalTo(QSLConst.qsl_kScreenW)
  691. make.height.equalTo(goodsBgHeight)
  692. }
  693. goodsBgView.addSubview(vipGoodsTitleIcon)
  694. vipGoodsTitleIcon.snp.makeConstraints { make in
  695. make.size.equalTo(CGSize(width: 117.rpx, height: 26.rpx))
  696. make.left.equalTo(20.rpx)
  697. make.top.equalTo(16.rpx)
  698. }
  699. goodsBgView.addSubview(resumeBtn)
  700. resumeBtn.snp.makeConstraints { make in
  701. make.size.equalTo(CGSize(width: 75.rpx, height: 16.rpx))
  702. make.right.equalTo(-18.rpx)
  703. make.centerY.equalTo(vipGoodsTitleIcon.snp.centerY)
  704. }
  705. goodsBgView.addSubview(mostCell)
  706. mostCell.snp.makeConstraints { make in
  707. make.left.equalTo(12.rpx)
  708. make.right.equalTo(-16.rpx)
  709. make.height.equalTo(113.rpx)
  710. make.top.equalTo(vipGoodsTitleIcon.snp.bottom).offset(10.rpx)
  711. }
  712. goodsBgView.addSubview(goodsCollectionView)
  713. goodsCollectionView.snp.makeConstraints { make in
  714. make.left.equalTo(12.rpx)
  715. make.right.equalTo(-18.rpx)
  716. make.bottom.equalTo(-20.rpx)
  717. make.top.equalTo(mostCell.snp.bottom).offset(3.rpx)
  718. }
  719. scrollView.snp.makeConstraints { make in
  720. make.bottom.equalTo(mainView)
  721. }
  722. self.view.addSubview(bottomContentView)
  723. bottomContentView.snp.makeConstraints { make in
  724. make.left.equalTo(12.rpx)
  725. make.right.equalTo(-12.rpx)
  726. make.bottom.equalTo(-QSLConst.qsl_kTabbarBottom)
  727. make.height.equalTo(72.rpx)
  728. }
  729. }
  730. }