QSLActivityVipVC.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. //
  2. // QSLActivityVipVC.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by Destiny on 2025/9/23.
  6. //
  7. import UIKit
  8. import GKCycleScrollView
  9. class QSLActivityVipVC: QSLBaseController {
  10. var goodList: [QSLGoodModel] = [QSLGoodModel]()
  11. var selectGood: QSLGoodModel? {
  12. didSet {
  13. updateSelectGoodUI()
  14. }
  15. }
  16. var currentCell: QSLVipMostGoodCell?
  17. override func viewDidLoad() {
  18. super.viewDidLoad()
  19. //gravityInstance?.track(QSLGravityConst.vip_show, properties: ["id": 1001])
  20. self.initializeView()
  21. self.requestNetwork()
  22. }
  23. @objc func payBtnAction() {
  24. }
  25. @objc func requestNetwork() {
  26. // 定义并赋值 itemListDict(根据条件变化)
  27. let itemListDict: [String: Any] = ["itemListType": 2]
  28. // 网络请求时使用 itemListDict 作为参数(关键修复)
  29. QSLNetwork().request(.vipActivityItemList(dict: itemListDict)) { response in
  30. // 后续逻辑不变...
  31. let list = response.mapArray(QSLGoodModel.self, modelKey: "data>list")
  32. self.goodList = list
  33. //TODO: 测试
  34. self.goodList += list
  35. self.goodList += list
  36. if self.goodList.count > 0 {
  37. self.goodList[0].isSelect = true
  38. self.selectGood = self.goodList[0]
  39. var height = 200.rpx
  40. if(self.goodList.count > 2){
  41. let row = (self.goodList.count-1)/2 + 1
  42. height = 124.rpx + row*124.rpx
  43. }
  44. self.vipItemView.snp.updateConstraints { make in
  45. make.height.equalTo(height)
  46. }
  47. self.scrollView.snp.makeConstraints { make in
  48. make.bottom.equalTo(self.vipItemView).offset(100)
  49. }
  50. //
  51. // self.checkRenewalOfProducts()
  52. }
  53. self.goodsCollectionView.reloadData()
  54. } fail: { code, error in
  55. self.view.toast(text: "加载商品列表失败")
  56. }
  57. }
  58. @objc func resumeBtnAction() {
  59. }
  60. lazy var scrollView: UIScrollView = {
  61. let scrollView = UIScrollView()
  62. // scrollView.delegate = self
  63. scrollView.bounces = false
  64. scrollView.showsVerticalScrollIndicator = false
  65. scrollView.contentInsetAdjustmentBehavior = .never
  66. return scrollView
  67. }()
  68. lazy var vipNaviView: UIView = {
  69. let view = UIView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW, QSLConst.qsl_kScreenH))
  70. view.addCorner(conrners: [.topLeft,.topRight], radius: 12.rpx)
  71. view.backgroundColor = UIColor.white
  72. return view
  73. }()
  74. lazy var naviTitleIcon: UILabel = {
  75. let label = UILabel()
  76. label.text("超值优惠")
  77. label.textColor = .white
  78. label.mediumFont(17)
  79. return label
  80. }()
  81. lazy var naviResumeBtn: UIButton = {
  82. let button = UIButton()
  83. button.title("恢复购买")
  84. button.setTitleColor(.white, for: .normal)
  85. button.titleLabel?.font = UIFont.systemFont(ofSize: 11, weight: .medium)
  86. button.image(UIImage(named: "vip_resume_btn")?.withTintColor(UIColor.white))
  87. button.setImageTitleLayout(.imgLeft, spacing: 2.rpx)
  88. button.addTarget(self, action: #selector(resumeBtnAction), for: .touchUpInside)
  89. return button
  90. }()
  91. lazy var backButton: UIButton = {
  92. let button = UIButton()
  93. button.image(UIImage(named: "vip_pay_failure_close"))
  94. button.addTarget(self, action: #selector(backBtnAction), for: .touchUpInside)
  95. return button
  96. }()
  97. lazy var vipBg: UIView = {
  98. let imageView = UIView()
  99. return imageView
  100. }()
  101. lazy var vipTopBg: UIImageView = {
  102. let imageView = UIImageView()
  103. imageView.image = UIImage(named: "vip_activity_top_bg")
  104. return imageView
  105. }()
  106. lazy var vipTopTitleView: UIImageView = {
  107. let imageView = UIImageView()
  108. imageView.image = UIImage(named: "vip_activity_top_title")
  109. return imageView
  110. }()
  111. lazy var vipDiamondView: UIButton = {
  112. let button = UIButton()
  113. button.image(UIImage(named: "vip_activity_top_diamond"))
  114. button.title("会员限时福利")
  115. button.font(14)
  116. button.textColor(.white)
  117. button.setImageTitleLayout(.imgLeft, spacing: 4.rpx)
  118. button.isUserInteractionEnabled = false
  119. return button
  120. }()
  121. lazy var vipContentView: UIView = {
  122. let view = UIView(frame: CGRectMake(0, 0, QSLConst.qsl_kScreenW, QSLConst.qsl_kScreenH))
  123. view.addCorner(conrners: [.topLeft,.topRight], radius: 12.rpx)
  124. view.backgroundColor = UIColor.white
  125. return view
  126. }()
  127. lazy var addTitleIcon: UILabel = {
  128. let label = UILabel()
  129. label.text("功能介绍")
  130. label.textColor = .hexStringColor(hexString: "#202020")
  131. label.boldFont(15)
  132. return label
  133. }()
  134. lazy var addTitleIconBg: UIView = {
  135. let view = UIView(frame: CGRectMake(0, 0, 117.rpx, 8.rpx))
  136. view.addRadius(radius: 4.rpx)
  137. // 创建渐变色层
  138. let gradientLayer = CAGradientLayer()
  139. gradientLayer.colors = [
  140. UIColor.hexStringColor(hexString: "#00DDAA",alpha: 1).cgColor,
  141. UIColor.hexStringColor(hexString: "#00DDAA",alpha: 0).cgColor
  142. ]
  143. gradientLayer.startPoint = CGPoint(x: 0, y: 0.4) // 左中
  144. gradientLayer.endPoint = CGPoint(x: 1, y: 0.4) // 右中
  145. gradientLayer.frame = view.bounds
  146. // 确保在布局变化时更新frame
  147. view.layer.insertSublayer(gradientLayer, at: 0)
  148. // 添加布局变化的监听
  149. view.layoutIfNeeded()
  150. view.layoutSubviews()
  151. return view
  152. }()
  153. lazy var cycleScrollView: GKCycleScrollView = {
  154. let cycleScrollView = GKCycleScrollView()
  155. cycleScrollView.dataSource = self
  156. cycleScrollView.delegate = self
  157. cycleScrollView.isAutoScroll = true
  158. cycleScrollView.isInfiniteLoop = true
  159. cycleScrollView.isChangeAlpha = false
  160. cycleScrollView.leftRightMargin = 12
  161. cycleScrollView.topBottomMargin = 12
  162. cycleScrollView.pageControl = pageControl
  163. cycleScrollView.reloadData()
  164. return cycleScrollView
  165. }()
  166. lazy var pageControl: GKPageControl = {
  167. let pageControl = GKPageControl()
  168. pageControl.style = .rectangle
  169. pageControl.dotHeight = 5.rpx
  170. pageControl.dotWidth = 5.rpx
  171. pageControl.dotMargin = 4.rpx
  172. pageControl.pageIndicatorTintColor = .hexStringColor(hexString: "#EEEEEE")
  173. pageControl.currentPageIndicatorTintColor = QSLColor.themeMainColor
  174. return pageControl
  175. }()
  176. lazy var vipItemView: UIView = {
  177. let item = UIView()
  178. return item
  179. }()
  180. lazy var goodsCollectionView: UICollectionView = {
  181. let layout = UICollectionViewFlowLayout()
  182. layout.minimumLineSpacing = 0
  183. layout.scrollDirection = .vertical
  184. let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
  185. collectionView.backgroundColor = .clear
  186. collectionView.dataSource = self
  187. collectionView.delegate = self
  188. collectionView.showsHorizontalScrollIndicator = false
  189. collectionView.bounces = false
  190. collectionView.register(cellClass: QSLActivityVipCell.self)
  191. return collectionView
  192. }()
  193. }
  194. extension QSLActivityVipVC{
  195. func updateSelectGoodUI(){
  196. }
  197. func initializeView() {
  198. self.view.addSubview(scrollView)
  199. scrollView.snp.makeConstraints { make in
  200. make.bottom.top.left.right.equalTo(0)
  201. }
  202. self.view.addSubview(vipNaviView)
  203. vipNaviView.snp.makeConstraints { make in
  204. make.top.left.right.equalTo(0)
  205. make.top.equalTo(QSLConst.qsl_kNavFrameH)
  206. }
  207. vipNaviView.addSubview(backButton)
  208. backButton.snp.makeConstraints { make in
  209. make.width.equalTo(44.rpx)
  210. make.height.equalTo(44.rpx)
  211. make.left.equalTo(10.rpx)
  212. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH)
  213. }
  214. vipNaviView.addSubview(naviTitleIcon)
  215. naviTitleIcon.snp.makeConstraints { make in
  216. make.centerX.equalToSuperview()
  217. make.width.equalTo(70.rpx)
  218. make.height.equalTo(20.rpx)
  219. make.centerY.equalTo(backButton.snp.centerY)
  220. }
  221. vipNaviView.addSubview(naviResumeBtn)
  222. naviResumeBtn.snp.makeConstraints { make in
  223. make.size.equalTo(CGSize(width: 70.rpx, height: 18.rpx))
  224. make.right.equalTo(-8.rpx)
  225. make.centerY.equalTo(backButton.snp.centerY)
  226. }
  227. self.scrollView.addSubview(vipBg)
  228. vipBg.snp.makeConstraints { make in
  229. make.top.bottom.left.equalTo(0)
  230. make.width.equalTo(QSLConst.qsl_kScreenW)
  231. }
  232. vipBg.addSubview(vipTopBg)
  233. vipTopBg.snp.makeConstraints { make in
  234. make.left.top.right.equalTo(0)
  235. make.height.equalTo(185.rpx)
  236. }
  237. vipTopBg.addSubview(vipTopTitleView)
  238. vipTopTitleView.snp.makeConstraints { make in
  239. make.left.equalTo(16.rpx)
  240. make.bottom.equalTo(vipTopBg.snp.bottom).offset(-16.rpx)
  241. make.height.equalTo(22.rpx)
  242. make.width.equalTo(183.rpx)
  243. }
  244. vipTopBg.addSubview(vipDiamondView)
  245. vipDiamondView.snp.makeConstraints { make in
  246. make.left.equalTo(16.rpx)
  247. make.bottom.equalTo(vipTopTitleView.snp.top).offset(-6.rpx)
  248. make.height.equalTo(20.rpx)
  249. make.width.equalTo(105.rpx)
  250. }
  251. vipBg.addSubview(vipContentView)
  252. vipContentView.snp.makeConstraints { make in
  253. make.top.equalTo(185.rpx)
  254. make.left.right.equalTo(0.rpx)
  255. make.height.equalTo(QSLConst.qsl_kScreenH)
  256. }
  257. vipContentView.addSubview(addTitleIconBg)
  258. addTitleIconBg.snp.makeConstraints { make in
  259. make.size.equalTo(CGSize(width: 117.rpx, height: 8.rpx))
  260. make.left.equalTo(16.rpx)
  261. make.top.equalTo(26.rpx)
  262. }
  263. vipContentView.addSubview(addTitleIcon)
  264. addTitleIcon.snp.makeConstraints { make in
  265. make.size.equalTo(CGSize(width: 157.rpx, height: 26.rpx))
  266. make.left.equalTo(20.rpx)
  267. make.top.equalTo(12.rpx)
  268. }
  269. vipContentView.addSubview(cycleScrollView)
  270. cycleScrollView.snp.makeConstraints { make in
  271. make.left.right.equalTo(0)
  272. make.height.equalTo(150.rpx)
  273. make.top.equalTo(50.rpx)
  274. }
  275. vipContentView.addSubview(pageControl)
  276. pageControl.snp.makeConstraints { make in
  277. make.size.equalTo(CGSize(width: 68.rpx, height: 4.rpx))
  278. make.centerX.equalToSuperview()
  279. make.top.equalTo(cycleScrollView.snp.bottom).offset(17.rpx)
  280. }
  281. vipContentView.addSubview(vipItemView)
  282. vipItemView.snp.makeConstraints { make in
  283. make.left.right.equalTo(0)
  284. make.height.equalTo(150.rpx)
  285. make.top.equalTo(pageControl.snp.bottom).offset(16.rpx)
  286. }
  287. vipItemView.addSubview(goodsCollectionView)
  288. goodsCollectionView.snp.makeConstraints { make in
  289. make.left.right.top.bottom.equalTo(0)
  290. }
  291. }
  292. }
  293. extension QSLActivityVipVC : GKCycleScrollViewDelegate, GKCycleScrollViewDataSource{
  294. func cycleScrollView(_ cycleScrollView: GKCycleScrollView!, cellForViewAt index: Int) -> GKCycleScrollViewCell! {
  295. if let cell = cycleScrollView.dequeueReusableCell() {
  296. cell.imageView.image = UIImage(named: "vip_activity_banner_\(index+1)")
  297. return cell
  298. }
  299. let cell = GKCycleScrollViewCell()
  300. cell.imageView.image = UIImage(named: "vip_activity_banner_\(index+1)")
  301. return cell
  302. }
  303. func numberOfCells(in cycleScrollView: GKCycleScrollView!) -> Int {
  304. return 3
  305. }
  306. func sizeForCell(in cycleScrollView: GKCycleScrollView!) -> CGSize {
  307. return CGSizeMake(QSLConst.qsl_kScreenW - 90.rpx, 150.rpx);
  308. }
  309. }
  310. extension QSLActivityVipVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  311. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  312. return goodList.count
  313. }
  314. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  315. let cell = collectionView.dequeueReusableCell(cellType: QSLActivityVipCell.self, cellForRowAt: indexPath)
  316. let model = self.goodList[indexPath.row]
  317. if (indexPath.row == 0) {
  318. cell.config(model: model, type: .top)
  319. } else {
  320. if(self.goodList.count > 2){
  321. cell.config(model: model, type: .small)
  322. }else{
  323. cell.config(model: model, type: .big)
  324. }
  325. }
  326. return cell
  327. }
  328. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  329. for index in 0..<self.goodList.count{
  330. var submodel = self.goodList[index]
  331. submodel.isSelect = false
  332. }
  333. var model = self.goodList[indexPath.row]
  334. model.isSelect = !model.isSelect
  335. // switch self.selectGood?.level {
  336. // case 100 :
  337. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1006])
  338. // break
  339. // case 700:
  340. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1005])
  341. // break;
  342. // case 3100:
  343. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1004])
  344. // break;
  345. // case 9200:
  346. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1003])
  347. // break;
  348. // case 36600:
  349. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1002])
  350. // break;
  351. // case 3660000:
  352. // gravityInstance?.track(QSLGravityConst.vip_good_select, properties: ["id": 1001])
  353. // break;
  354. // default:
  355. // break;
  356. // }
  357. self.goodsCollectionView.reloadData()
  358. }
  359. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  360. if (indexPath.row == 0) {
  361. return CGSize(width: QSLConst.qsl_kScreenW-32.rpx, height: 112.rpx)
  362. } else {
  363. if(self.goodList.count == 2){
  364. return CGSize(width: QSLConst.qsl_kScreenW-32.rpx, height: 72.rpx)
  365. }else{
  366. return CGSize(width: (QSLConst.qsl_kScreenW-50.rpx)/2.0, height: 112.rpx)
  367. }
  368. }
  369. }
  370. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
  371. return UIEdgeInsets(top: 0, left: 16.rpx, bottom: 0, right: 16.rpx)
  372. }
  373. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  374. return 10.rpx
  375. }
  376. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  377. if(self.goodList.count == 2){
  378. return 10.rpx
  379. }else{
  380. return 16.rpx
  381. }
  382. }
  383. }