// // MyFavoriteViewController.swift // MTP2_iOS // // Created by Handy_Cao on 2020/10/29. // Copyright © 2020 Muchinfo. All rights reserved. // import UIKit import WHToast import SwiftyAttributes import GTMRefresh /// 我的收藏夹视图容器控制类 class MyFavoriteViewController: BaseViewController { // MARK: - 属性列表 /// 商品数据集合视图 @IBOutlet weak var collectionView: UICollectionView! { didSet { if collectionView.responds(to: #selector(setter: UICollectionView.isPrefetchingEnabled)) { collectionView.isPrefetchingEnabled = false } /// 设置约束 collectionView.setCollectionViewLayout(flowLayout, animated: true) } } /// 数据显示集合视图约束 lazy var flowLayout: UICollectionViewFlowLayout = { /// 最小行间距,默认是0 $0.minimumLineSpacing = 0 /// 最小左右间距,默认是10 $0.minimumInteritemSpacing = 0 /// 区域内间距,默认是 UIEdgeInsetsMake(0, 0, 0, 0) $0.sectionInset = UIEdgeInsets(top: 0.0, left: 0, bottom: 0, right: 0) /// 水平滚动 $0.scrollDirection = .vertical return $0 } (UICollectionViewFlowLayout()) /// GoodsCellIdentifier let GoodsCellIdentifier = "Goods_Cell" /// 商品数据信息 var goods: [MoGoodsInfo] = [] { didSet { /// 刷新数据 collectionView.reloadData() /// 是否隐藏按钮 self.noDataButton.isHidden = goods.count != 0 if goods.count > 0 { /// 等待UI操作完成,也就是tableView刷新完之后执行 DispatchQueue.main.async { [weak self] in if self?.visibleGoodsCodes.count != 0 { self?.shouldSubscriptGoodsCodes = self?.visibleGoodsCodes } } } } } // MARK: - 生命周期 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. /// UI界面初始化 buildView() /// 数据初始化 initData() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) /// 隐藏导航栏 self.navigationController?.setNavigationBarHidden(false, animated: true) // 侦听行情推送广播 MTP2BusinessCore.shared.broadcastManager?.addBroadcastListener(owner: self, action: .ReceiveTradeQuote) { [weak self] in guard let quoteGoodsInfos = $0.object as? [(goodsHqCode: String, exchHqCode: String)], let goodsManager = MTP2BusinessCore.shared.goodsManager, let weakSelf = self else { return } /// 有数据 if quoteGoodsInfos.count != 0 { /// 待刷新行 var refreshIndexPaths = [IndexPath]() DispatchQueue.main.async { for (index, cell) in weakSelf.collectionView.visibleCells.enumerated() { if quoteGoodsInfos.first(where: { $0.goodsHqCode == (cell as? GoodsCell)?.model?.goodscode }) != nil { let indexPath = IndexPath(row: index, section: 0) if refreshIndexPaths.firstIndex(of: indexPath) == nil { /// 更新显示行情数据 guard let moGoodsInfo = goodsManager.goodsInfos.first(where: { $0.goodscode == (cell as? GoodsCell)?.model?.goodscode }) else { continue } if (cell as? GoodsCell)?.model?.moQuoteInfo?.last != moGoodsInfo.moQuoteInfo?.last { (cell as? GoodsCell)?.price.attributedText = (moGoodsInfo.currencysign+" \(moGoodsInfo.moQuoteInfo?.last.toDownString(reserve: moGoodsInfo.decimalplace) ?? "0.0")").withTextColor(.red).withFont(.font_22) /// 记录待刷新行 /// 判断是否在可见区域 if weakSelf.collectionView.indexPathsForVisibleItems.firstIndex(of: indexPath) != nil { refreshIndexPaths.append(indexPath) } } } } } } /// 刷新行情列表 if refreshIndexPaths.count > 0 { DispatchQueue.main.async { weakSelf.collectionView.reloadItems(at: refreshIndexPaths) } } } } } deinit { /// 清除广播侦听 MTP2BusinessCore.shared.broadcastManager?.removeBroadcastListener(owner: self, forName: .ReceiveTradeQuote) } // MARK: - 数据初始化 /// 数据初始化 fileprivate func initData() { /// 获取用户收藏商品数据信息 requestQueryUserFavoriteGoodses() } /// UI界面初始化 fileprivate func buildView() { /// loding...... addLoadingView() /// 添加下拉刷新控件 self.collectionView.gtm_addRefreshHeaderView(refreshHeader: DefaultGTMRefreshHeader()) { /// 重置请求条件 self.requestQueryUserFavoriteGoodses() } } // MARK: - 接口请求 /// 获取用户收藏商品数据信息 fileprivate func requestQueryUserFavoriteGoodses() { /// 异常 guard let goodsManager = MTP2BusinessCore.shared.goodsManager, let accountid = MTP2BusinessCore.shared.accountManager?.getCurrentTAAccountInfo()?.accountId else { return } /// startAnimating self._anim?.startAnimating() /// 发送请求 goodsManager.requestQueryUserFavoriteGoodses { (isComplete, error, goodsid) in DispatchQueue.main.async { /// stopAnimating self._anim?.stopAnimating() /// endRefreshing self.collectionView.endRefreshing(isSuccess: true) if isComplete { var showGoods: [MoGoodsInfo] = [], shopGoodsIds: [String] = [] for obj in (goodsid ?? []) { if let good = MTP2BusinessCore.shared.goodsManager?.goodsInfos.first(where: {$0.goodsid == obj}), good.trademode != .TRADEMODE_TRADEMODE_HSBY_SHOP { /// 商城单独处理 showGoods.append(good) } else { /// 商城goods单独拉出来鞭尸 shopGoodsIds.append("\(obj)") } } var ids = "" for (index, id) in shopGoodsIds.enumerated() { ids += index != shopGoodsIds.count-1 ? "\(id)," : "\(id)" } /// 简直是狗屎设计啊 goodsManager.requestQueryHsbyMarketGoodses(goodsManager.getMarketIDs(.TRADEMODE_TRADEMODE_HSBY_SHOP), accountid, nil, ids, nil) { (isSuccess, error, infos) in DispatchQueue.main.async { /// 数据获取成功 showGoods.append(contentsOf: infos?.sorted(by: { (obj1, obj2) -> Bool in return (obj1.orderqty-obj1.tradeqty-obj1.cancelqty)>(obj2.orderqty-obj2.tradeqty-obj2.cancelqty) }) ?? []) /// 展示商品 self.goods = showGoods } } } else { self.goods = [] /// toast WHToast.showError(withMessage: "数据获取失败,原因:\(error?.retMsg ?? "未知错误")", duration: 1.0, finishHandler: {}) } } } } // MARK: - 订阅行情相关 var uuid: String = UUID().uuidString var shouldSubscriptGoodsCodes: Set? { didSet { guard let quoteSubscriptManager = MTP2BusinessCore.shared.quoteSubscriptManager else { return } quoteSubscriptManager.updateQuoteSubcriptGoods(uuid: uuid, goodsCode: shouldSubscriptGoodsCodes ?? []) } } var visibleGoodsCodes: Set { var goodsCodes = Set() self.collectionView.visibleCells.forEach { (cell) in if let quoteCell = cell as? GoodsCell, let goodsCode = quoteCell.model?.goodscode { goodsCodes.insert(goodsCode) } } return goodsCodes } // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. if segue.identifier == "ShowGoodsDetail" { /// 商品详情 (segue.destination as? GoodsDetailViewController)?.model = (sender as? GoodsCell)?.model } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } // MARK: - UIScrollViewDelegate extension MyFavoriteViewController: UIScrollViewDelegate { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if visibleGoodsCodes.count != 0 { shouldSubscriptGoodsCodes = visibleGoodsCodes } } } // MARK: - UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout extension MyFavoriteViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.goods.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GoodsCellIdentifier, for: indexPath) as! GoodsCell cell.model = self.goods[indexPath.item] return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: collectionView.width/2, height: ((collectionView.width/2)*0.9)+80.0) } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { /// 商品详情 let goodsDetailController = UIStoryboard(name: "Quote", bundle: nil).instantiateViewController(withIdentifier: "GoodsDetail") as! GoodsDetailViewController goodsDetailController.model = self.goods[indexPath.row] self.navigationController?.pushViewController(goodsDetailController, animated: true) } }