MyFavoriteViewController.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //
  2. // MyFavoriteViewController.swift
  3. // MTP2_iOS
  4. //
  5. // Created by Handy_Cao on 2020/10/29.
  6. // Copyright © 2020 Muchinfo. All rights reserved.
  7. //
  8. import UIKit
  9. import WHToast
  10. import SwiftyAttributes
  11. import GTMRefresh
  12. /// 我的收藏夹视图容器控制类
  13. class MyFavoriteViewController: BaseViewController {
  14. // MARK: - 属性列表
  15. /// 商品数据集合视图
  16. @IBOutlet weak var collectionView: UICollectionView! {
  17. didSet {
  18. if collectionView.responds(to: #selector(setter: UICollectionView.isPrefetchingEnabled)) {
  19. collectionView.isPrefetchingEnabled = false
  20. }
  21. /// 设置约束
  22. collectionView.setCollectionViewLayout(flowLayout, animated: true)
  23. }
  24. }
  25. /// 数据显示集合视图约束
  26. lazy var flowLayout: UICollectionViewFlowLayout = {
  27. /// 最小行间距,默认是0
  28. $0.minimumLineSpacing = 0
  29. /// 最小左右间距,默认是10
  30. $0.minimumInteritemSpacing = 0
  31. /// 区域内间距,默认是 UIEdgeInsetsMake(0, 0, 0, 0)
  32. $0.sectionInset = UIEdgeInsets(top: 0.0, left: 0, bottom: 0, right: 0)
  33. /// 水平滚动
  34. $0.scrollDirection = .vertical
  35. return $0
  36. } (UICollectionViewFlowLayout())
  37. /// GoodsCellIdentifier
  38. let GoodsCellIdentifier = "Goods_Cell"
  39. /// 商品数据信息
  40. var goods: [MoGoodsInfo] = [] {
  41. didSet {
  42. /// 刷新数据
  43. collectionView.reloadData()
  44. /// 是否隐藏按钮
  45. self.noDataButton.isHidden = goods.count != 0
  46. if goods.count > 0 {
  47. /// 等待UI操作完成,也就是tableView刷新完之后执行
  48. DispatchQueue.main.async { [weak self] in
  49. if self?.visibleGoodsCodes.count != 0 { self?.shouldSubscriptGoodsCodes = self?.visibleGoodsCodes }
  50. }
  51. }
  52. }
  53. }
  54. // MARK: - 生命周期
  55. override func viewDidLoad() {
  56. super.viewDidLoad()
  57. // Do any additional setup after loading the view.
  58. /// UI界面初始化
  59. buildView()
  60. /// 数据初始化
  61. initData()
  62. }
  63. override func viewWillAppear(_ animated: Bool) {
  64. super.viewWillAppear(animated)
  65. /// 隐藏导航栏
  66. self.navigationController?.setNavigationBarHidden(false, animated: true)
  67. // 侦听行情推送广播
  68. MTP2BusinessCore.shared.broadcastManager?.addBroadcastListener(owner: self, action: .ReceiveTradeQuote) { [weak self] in
  69. guard let quoteGoodsInfos = $0.object as? [(goodsHqCode: String, exchHqCode: String)],
  70. let goodsManager = MTP2BusinessCore.shared.goodsManager,
  71. let weakSelf = self else { return }
  72. /// 有数据
  73. if quoteGoodsInfos.count != 0 {
  74. /// 待刷新行
  75. var refreshIndexPaths = [IndexPath]()
  76. DispatchQueue.main.async {
  77. for (index, cell) in weakSelf.collectionView.visibleCells.enumerated() {
  78. if quoteGoodsInfos.first(where: { $0.goodsHqCode == (cell as? GoodsCell)?.model?.goodscode }) != nil {
  79. let indexPath = IndexPath(row: index, section: 0)
  80. if refreshIndexPaths.firstIndex(of: indexPath) == nil {
  81. /// 更新显示行情数据
  82. guard let moGoodsInfo = goodsManager.goodsInfos.first(where: { $0.goodscode == (cell as? GoodsCell)?.model?.goodscode }) else { continue }
  83. if (cell as? GoodsCell)?.model?.moQuoteInfo?.last != moGoodsInfo.moQuoteInfo?.last {
  84. (cell as? GoodsCell)?.price.attributedText = (moGoodsInfo.currencysign+" \(moGoodsInfo.moQuoteInfo?.last.toDownString(reserve: moGoodsInfo.decimalplace) ?? "0.0")").withTextColor(.red).withFont(.font_22)
  85. /// 记录待刷新行
  86. /// 判断是否在可见区域
  87. if weakSelf.collectionView.indexPathsForVisibleItems.firstIndex(of: indexPath) != nil {
  88. refreshIndexPaths.append(indexPath)
  89. }
  90. }
  91. }
  92. }
  93. }
  94. }
  95. /// 刷新行情列表
  96. if refreshIndexPaths.count > 0 {
  97. DispatchQueue.main.async {
  98. weakSelf.collectionView.reloadItems(at: refreshIndexPaths)
  99. }
  100. }
  101. }
  102. }
  103. }
  104. deinit {
  105. /// 清除广播侦听
  106. MTP2BusinessCore.shared.broadcastManager?.removeBroadcastListener(owner: self, forName: .ReceiveTradeQuote)
  107. }
  108. // MARK: - 数据初始化
  109. /// 数据初始化
  110. fileprivate func initData() {
  111. /// 获取用户收藏商品数据信息
  112. requestQueryUserFavoriteGoodses()
  113. }
  114. /// UI界面初始化
  115. fileprivate func buildView() {
  116. /// loding......
  117. addLoadingView()
  118. /// 添加下拉刷新控件
  119. self.collectionView.gtm_addRefreshHeaderView(refreshHeader: DefaultGTMRefreshHeader()) {
  120. /// 重置请求条件
  121. self.requestQueryUserFavoriteGoodses()
  122. }
  123. }
  124. // MARK: - 接口请求
  125. /// 获取用户收藏商品数据信息
  126. fileprivate func requestQueryUserFavoriteGoodses() {
  127. /// 异常
  128. guard let goodsManager = MTP2BusinessCore.shared.goodsManager,
  129. let accountid = MTP2BusinessCore.shared.accountManager?.getCurrentTAAccountInfo()?.accountId else {
  130. return
  131. }
  132. /// startAnimating
  133. self._anim?.startAnimating()
  134. /// 发送请求
  135. goodsManager.requestQueryUserFavoriteGoodses { (isComplete, error, goodsid) in
  136. DispatchQueue.main.async {
  137. /// stopAnimating
  138. self._anim?.stopAnimating()
  139. /// endRefreshing
  140. self.collectionView.endRefreshing(isSuccess: true)
  141. if isComplete {
  142. var showGoods: [MoGoodsInfo] = [], shopGoodsIds: [String] = []
  143. for obj in (goodsid ?? []) {
  144. if let good = MTP2BusinessCore.shared.goodsManager?.goodsInfos.first(where: {$0.goodsid == obj}),
  145. good.trademode != .TRADEMODE_TRADEMODE_HSBY_SHOP { /// 商城单独处理
  146. showGoods.append(good)
  147. } else { /// 商城goods单独拉出来鞭尸
  148. shopGoodsIds.append("\(obj)")
  149. }
  150. }
  151. var ids = ""
  152. for (index, id) in shopGoodsIds.enumerated() {
  153. ids += index != shopGoodsIds.count-1 ? "\(id)," : "\(id)"
  154. }
  155. /// 简直是狗屎设计啊
  156. goodsManager.requestQueryHsbyMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), accountid, nil, ids, nil) { (isSuccess, error, infos) in
  157. DispatchQueue.main.async {
  158. /// 数据获取成功
  159. showGoods.append(contentsOf: infos?.sorted(by: { (obj1, obj2) -> Bool in
  160. return (obj1.orderqty-obj1.tradeqty-obj1.cancelqty)>(obj2.orderqty-obj2.tradeqty-obj2.cancelqty)
  161. }) ?? [])
  162. /// 展示商品
  163. self.goods = showGoods
  164. }
  165. }
  166. } else {
  167. self.goods = []
  168. /// toast
  169. WHToast.showError(withMessage: "数据获取失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.0, finishHandler: {})
  170. }
  171. }
  172. }
  173. }
  174. // MARK: - 订阅行情相关
  175. var uuid: String = UUID().uuidString
  176. var shouldSubscriptGoodsCodes: Set<String>? {
  177. didSet {
  178. guard let quoteSubscriptManager = MTP2BusinessCore.shared.quoteSubscriptManager else { return }
  179. quoteSubscriptManager.updateQuoteSubcriptGoods(uuid: uuid, goodsCode: shouldSubscriptGoodsCodes ?? [])
  180. }
  181. }
  182. var visibleGoodsCodes: Set<String> {
  183. var goodsCodes = Set<String>()
  184. self.collectionView.visibleCells.forEach { (cell) in
  185. if let quoteCell = cell as? GoodsCell,
  186. let goodsCode = quoteCell.model?.goodscode {
  187. goodsCodes.insert(goodsCode)
  188. }
  189. }
  190. return goodsCodes
  191. }
  192. // MARK: - Navigation
  193. // In a storyboard-based application, you will often want to do a little preparation before navigation
  194. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  195. // Get the new view controller using segue.destination.
  196. // Pass the selected object to the new view controller.
  197. if segue.identifier == "ShowGoodsDetail" {
  198. /// 商品详情
  199. (segue.destination as? GoodsDetailViewController)?.model = (sender as? GoodsCell)?.model
  200. }
  201. }
  202. /*
  203. // MARK: - Navigation
  204. // In a storyboard-based application, you will often want to do a little preparation before navigation
  205. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  206. // Get the new view controller using segue.destination.
  207. // Pass the selected object to the new view controller.
  208. }
  209. */
  210. }
  211. // MARK: - UIScrollViewDelegate
  212. extension MyFavoriteViewController: UIScrollViewDelegate {
  213. func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
  214. if visibleGoodsCodes.count != 0 { shouldSubscriptGoodsCodes = visibleGoodsCodes }
  215. }
  216. }
  217. // MARK: - UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
  218. extension MyFavoriteViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  219. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  220. return self.goods.count
  221. }
  222. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  223. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GoodsCellIdentifier, for: indexPath) as! GoodsCell
  224. cell.model = self.goods[indexPath.item]
  225. return cell
  226. }
  227. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
  228. return CGSize(width: collectionView.width/2, height: ((collectionView.width/2)*0.9)+80.0)
  229. }
  230. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  231. /// 商品详情
  232. let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController
  233. goodsDetailController.model = self.goods[indexPath.row]
  234. self.navigationController?.pushViewController(goodsDetailController, animated: true)
  235. }
  236. }